学做家常菜的网站有哪些,营销网站的主题 定位 修改建议,杭州企业营销网站建设公司,食品网站的网页设计1006Touhou Red Red Blue
dp
设状态方程为前i个数中#xff0c;当前第一个包里面的是0/1/2/3状态#xff0c;第二个包里面是0/1/2/3状态
0代表着还没有颜色#xff0c;1代表R#xff0c;2代表G#xff0c;3代笔B颜色
初始状态都没选择颜色所以都是状态0
没选择颜色只…1006Touhou Red Red Blue
dp
设状态方程为前i个数中当前第一个包里面的是0/1/2/3状态第二个包里面是0/1/2/3状态
0代表着还没有颜色1代表R2代表G3代笔B颜色
初始状态都没选择颜色所以都是状态0
没选择颜色只能从后面的字符里面选
细想操作一 a b两个包清空然后a选择任意颜色b从后面的选
换句话说就是a的颜色要取决于后面的颜色所以不如直接让b变成任意颜色a状态变成0
后面选择的字符放到a其实是等效的且这样遍历
else f[i][b][c]max(f[i][b][c],f[i-1][a][b]);
我不用另外判断这个条件
#includebits/stdc.h
using namespace std;
const int N 1e510,mod998244353;typedef long long LL;
typedef pairint, int PII;int n;
int f[N][5][5];
int get(char c){if(cR) return 1;else if(cG) return 2;else return 3;
}void solve(){memset(f,-0x3f,sizeof(f));string s;cins;ns.size();s?s;f[0][0][0]0;for(int i1;in;i){int cget(s[i]);for(int a0;a3;a){for(int b0;b3;b){f[i][a][b]f[i-1][a][b];}}for(int a0;a3;a){for(int b0;b3;b){if(abbc){for(int d1;d3;d){f[i][0][d]max(f[i][0][d],f[i-1][a][b]1);}}else if(abca!ba!cb!c){for(int d1;d3;d){for(int e1;e3;e){f[i][d][e]max(f[i][d][e],f[i-1][a][b]);}}}else f[i][b][c]max(f[i][b][c],f[i-1][a][b]);}}}int res0;for(int a0;a3;a){for(int b0;b3;b)resmax(res,f[n][a][b]);}coutres\n;
}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t1;cint;while(t--) solve();
} 1012Counting Stars
首先统计度数
k星图可以由
k1星图选择去掉其中1条边里面的其中一条变成
k2星图选择去掉其中2条边里面的其中两条变成
...
所以直接统计度数即可
然后每个点暴力枚举2到d[i]的k星图增加个数即可
复杂度是nm
#includebits/stdc.h
using namespace std;
const int N 1e610,mod1e97;
#define int long long
typedef long long LL;
typedef pairint, int PII;
int n,m,k;
int fact[N],infact[N];
int qmi(int a, int k, int p) // 求a^k mod p
{int res 1 % p;while (k){if (k 1) res (LL)res * a % p;a (LL)a * a % p;k 1;}return res;
}void init(){fact[0] infact[0] 1;for (int i 1; i N; i ){fact[i] (LL)fact[i - 1] * i % mod;infact[i] (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;}
}
int C(int a,int b){if(ba) return 0;return ((LL)fact[a] * infact[b] % mod * infact[a - b] % mod);
}
void solve(){int n,m;cinnm;vectorint d(n10,0),ans(n10,0);for(int i1;im;i){int a,b;cinab;d[a],d[b];}for(int i1;in;i){long long tmpd[i]*(d[i]-1)/2%mod;for(int j2;jd[i];j){ans[j](ans[j]C(d[i],j))%mod;}} long long res0;for(int i2;in-1;i)res^ans[i];coutres\n;
}signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t1;init();cint;while(t--) solve();
} 1007Expectation (Easy Version)
直接枚举即可
当前i 贡献是i^m,概率是n场里面选择i场赢赢i场的概率*输(n-i)场的概率
#includebits/stdc.h
using namespace std;
const int N 1e610,mod998244353;
#define int long long
typedef long long LL;
typedef pairint, int PII;int n;
int a[N],b[N];
int fact[N],infact[N];
int qmi(int a, int k, int p) // 求a^k mod p
{int res 1 % p;while (k){if (k 1) res (LL)res * a % p;a (LL)a * a % p;k 1;}return res;
}void init(){fact[0] infact[0] 1;for (int i 1; i N; i ){fact[i] (LL)fact[i - 1] * i % mod;infact[i] (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;}
}
int C(int a,int b){if(ba) return 0;return ((LL)fact[a] * infact[b] % mod * infact[a - b] % mod);
}
int gcd(int a, int b) // 欧几里得算法
{return b ? gcd(b, a % b) : a;
}
void solve(){int n,m,x,y;cinnmxy;int winx*qmi(y,mod-2,mod)%mod;int sum0,ans0;a[0]b[0]1;for(int i1;in;i) a[i]a[i-1]*win%mod;for(int i1;in;i) b[i]b[i-1]*(1-winmod)%mod;for(int i1;in;i){sum(sumqmi(i,m,mod))%mod;int resC(n,i)*a[i]%mod*b[n-i]%mod*sum%mod;ans(ansres)%mod;}cout(ansmod)%mod\n;
}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t1;init();cint;while(t--) solve();
}
1003String Magic (Easy Version)
对于每个下标 用合法的起点减去不合法的终点就是答案了注释在代码里
要用到马拉车算法求出f[ ]数组就是以i为中心的回文字符串的长度
每个字符串对应一个
#includebits/stdc.h
using namespace std;
const int N 3e510,mod998244353;typedef long long LL;
typedef pairint, int PII;
int n;
char ss[N];
int f[N];
int sum[N];
vectorint V[N];
int tr[N];
int lowbit(int x)
{return x -x;
}void add(int x, int c) // 位置x加c
{while(x){tr[x]c;x-lowbit(x);}
}int query(int x) // 返回前x个数的和
{int res 0;while(xnn){restr[x];xlowbit(x);}return res;
}void solve(){int ans0;string s;cins;ns.size();s?s;ss[0]?;ss[nn2]^;for(int i1;in;i){ss[ii-1]*;ss[ii]s[i];ss[ii1]*;}for(int i1;inn;i) V[i].clear(),tr[i]0,f[i]0;int mr0,mid0;for(int i1;ss[i]!^;i){if(imr) f[i]min(mr-i,f[2*mid-i]);else f[i]1;while(ss[if[i]]ss[i-f[i]]) f[i];if(f[i]imr){mrf[i]i;midi;}}for(int i1;inn;i) f[i]--;//f[i]是求每个点为中心的最长回文串的长度for(int i3;inn;i){if(i%20) continue;V[i-1].push_back(i);//有个性质*号的位置如果长度不是1那么他对应的字符串长度一定是偶数//不是*号的字母回文字符一定包含*号 *a* 所以这是合法对数的起点V[i-(f[i]1)/2-1].push_back(-i);//i-(f[i]1)/2-1 的点就已经不在i的回文范围内了}for(int i1;inn;i){add(if[i],1);//当前i能扩展到右边的端点位置for(auto v:V[i]){if(v0) ansquery(v);else ans-query(-v);//相当于起点减去终点}}coutans\n;
}
signed main(){cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);int t1;cint;while(t--) solve();
}