250
ImportantSequence
题意:告诉你相邻两数的操作符和运算结果,求有多少满足要求的正整数序列
分析:固定了第一个数,答案就固定,由于有每个数都是正整数的限制,因此可以把限制都转移到第一个数上,把每个数用第一个数表示,就可以得到一系列不等式,解一下即可
550
RandomColoring
题意:定义颜色为(R,G,B)的三元祖,给定一个初始颜色,按照某种规则生成等概率生成下一种颜色,问最后一种颜色和第一种颜色仍然满足这种规则的概率
分析:由于数据范围都只有50,可以考虑暴力dp,复杂度显然事
O(n7)
无法满足,但计算dp[i][j][k]就相当于求三维空间中一个长方体中的所有数的和,于是可以可以求一个三位前缀和来搞;
注意求这个前缀和需要for三次(最后一维不同即可),而求区间和需要一个容斥,具体来说就是sum((xl,xr],(yl,yr],(zl,zr])是二维形式的推广
950
ProductQuery
题意:给出若干个区间乘积mod10的结果,求有多少个元素<10的非负整数数列
假如把10改成任意一个质数,那么就可以求逆元,意味着算pro[l,r]==x方案可以让[l,r-1]的数任选,前面一个数确定了最后一个数就确定了
本题稍微复杂一些,有多个区间,不过我们只关心右端点重合的那些区间,只需要把这些区间按照左端点从小到大排序,然后把大区间拆掉即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>
#include <fstream>
using namespace std;
typedef long long LL;
typedef pair<int,int>pi;
const int M=1e9+7;
inline void up(int &x,int y){
x+=y;if(x>=M)x-=M;
}
class ProductQuery {
public:
int notzero[222];
vector<pi>V[222];
int pw[222];
int dp[222];
int cal(int a,int b,int p){//ret*a%p==b
for(int i=1;i<p;i++)if(i*a%p==b)return i;
return -1;
}
int solve(int N,vector<int>ql,vector<int>qr,vector<int>res,int p){
int q=res.size();
pw[0]=1;
for(int i=1;i<=N+2;i++)pw[i]=1LL*pw[i-1]*(p-1)%M;
for(int i=0;i<q;i++){
res[i]=res[i]%p;
}
memset(notzero,0,sizeof(notzero));
for(int i=0;i<q;i++){
if(res[i]){
for(int j=ql[i];j<=qr[i];j++)notzero[j]=1;
}
}
//
dp[0]=1;
for(int i=1;i<=N+1;i++){
dp[i]=0;
if(notzero[i])continue;
for(int j=0;j<i;j++){
if(dp[j]){
bool flag=1;
for(int k=0;k<q;k++){
if(!res[k]&&ql[k]>j&&qr[k]<i){
flag=0;
break;
}
}
if(flag){
int cnt=0;
for(int tmp=j+1;tmp<i;tmp++)if(!notzero[tmp])cnt++;
up(dp[i],1LL*pw[cnt]*dp[j]%M);
}
}
}
}
if(!dp[N+1])return 0;
for(int i=1;i<=N;i++)V[i].clear();
for(int i=0;i<q;i++)if(res[i])V[qr[i]].push_back(pi(ql[i],res[i]));
int det=0;
for(int i=N;i>=1;i--){
if(!notzero[i]||!V[i].size())continue;
sort(V[i].begin(),V[i].end());
for(int j=V[i].size()-2;j>=0;j--){
if(V[i][j].first==V[i][j+1].first){
if(V[i][j].second!=V[i][j+1].second)return 0;
}
else{
int t=cal(V[i][j+1].second,V[i][j].second,p);//cal(a,b,p)*a==b%p
V[V[i][j+1].first-1].push_back(pi(V[i][j].first,t));
}
}
det++;
}
int tot=0;
for(int i=1;i<=N;i++)if(notzero[i])tot++;
//if(p==5)printf("tot=%d det=%d\n",tot,det);
int ans=1LL*pw[tot-det]*dp[N+1]%M;
return ans;
}
int theInput(int N, vector<int> Qfrom, vector<int> Qto, vector<int> output) {
for(int i=0;i<Qfrom.size();i++){
Qfrom[i]++,Qto[i]++;
}
return 1LL*solve(N,Qfrom,Qto,output,2)*solve(N,Qfrom,Qto,output,5)%M;
return 0;
}
};