子段乘积
尺取法就完事熬
#include#include using namespace std; typedef long long ll; int mod = 998244353; template void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } inline int mul(int x,int y){return 1ll*x*y%mod;} inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;} inline int sub(int x,int y){return x-y<0?x-y+mod:x-y;} inline int sq(int x){return 1ll*x*x%mod;} int pow(int a,int b){return b == 0 ? 1 : ( b&1 ? mul(a,sq(pow(a,b/2))) : sq(pow(a,b/2)));} int n,k,a[1000010]; int main(){ read(n);read(k); for(int i=1;i<=n;i++){ read(a[i]); } int ans = 0,md = 1,cnt = 0; for(int i=1;i<=k;i++){ if(a[i] == 0){ cnt++; }else{ md = mul(md,a[i]); } } for(int i=1;i+k-1<=n;i++){ if(!cnt)ans = max(ans,md); if(a[i] == 0)cnt--; else md = mul(md,pow(a[i],mod-2)); if(a[i+k] == 0)cnt++; else md = mul(md,a[i+k]); } cout<
子段异或,首先从第一个数开始不断地异或到最后,异或过程中一个值重复出现,就说明这两个值之间出现一段异或起来为0的;
#include#define debug(x) cerr<<#x<<'='< pii; template void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } ll n,a[200010],ans = 0; map Mp; int main() { read(n); ll csu = 0; Mp[0] = 1; for(int i=0;i
最小表达式
#includeusing namespace std; typedef long long ll; int cnt[20]; int sum[500050]; char s[500050]; int main() { cin>>s; int ccnt = 1; int n = strlen(s); for(int i=0;i =1;i--){ while(cnt[i]){ sum[cp]+=i; cnt[i]-=1; p = (p+1)%ccnt; if(p == 0)cp+=1; } } for(int i=0;i<500010;i++){ sum[i+1]+=sum[i]/10; sum[i]%=10; } int opt = 0; for(int i=500010;i>=0;i--){ if(opt || sum[i]){ cout<
树上博弈
作者:nocriz
链接:https://www.nowcoder.com/discuss/365889
来源:牛客网
首先,注意到输掉的唯一方法是自己的唯一一条边有另一个人,那么自己一定是在叶子上。
令两个人之间的距离为D。请注意,每人行动后D增加1或减少1。 因此,每有人走一步D的奇偶性都会改变。
假设最初,在牛牛移动之前,D是偶数。 那么当牛牛移动时D将始终为偶数,而当牛妹移动时D将始终为奇数。
请注意,只要牛牛和牛妹的令牌位于相邻的节点中,D=1。因此,如果D为偶数,则他们不在相邻的单元格中,并且牛牛始终可以移动。
另一方面,由于牛牛总是可以移动,因此他可以向牛妹的方向移动,将牛妹必然会最终移动到叶子上。同样,如果最初D是奇数,则牛妹获胜。
因此,答案取决于距离的奇偶性:如果是偶数,则牛牛获胜,否则牛妹获胜。
可以发现,只有牛牛的初始位置和牛妹的初始位置距离为偶数时,牛牛获胜。只需要分别求出深度为奇数的点和深度为偶数的点的数量即可。
#include#define debug(x) cerr<<#x<<'='< pii; template void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } template void read(T &first, Args& ... args) { read(first); read(args...); } int n,q,x,y,depth[1000010]; ll cnt[2]; int main() { read(n); depth[1] = 0; cnt[0] = 1; for(int i=2;i<=n;i++){ int cc; read(cc); depth[i] = depth[cc]^1; cnt[depth[i]]+=1; } cout<
作者:nocriz
链接:https://www.nowcoder.com/discuss/365889
来源:牛客网
音乐鉴赏
如果随机占比为 xxx ,一个人分数为 scorescorescore ,那么他优秀的概率为 (score−90)(1−x)90x\frac{(score-90)(1-x)}{90x}90x(score−90)(1−x)。
这个概率可以这么计算:首先把分数减90,大于0就优秀,那么就变成(score−90)∗(1−x)−y∗x≥0(score-90)*(1-x)-y*x\ge 0(score−90)∗(1−x)−y∗x≥0,其中y是一个随机的0到90之间的数字。(score−90)∗(1−x)≥y∗x(score-90)*(1-x)\ge y*x(score−90)∗(1−x)≥y∗x,(score−90)∗(1−x)x≥y\frac{(score-90)*(1-x)}{x}\ge yx(score−90)∗(1−x)≥y,这个概率就是上面所写的概率。
E=∑i=1n(scorei−90)(1−x)90x=0.1nE=\sum_{i=1}^{n} \frac{(score_i-90)(1-x)}{90x}=0.1nE=∑i=1n90x(scorei−90)(1−x)=0.1n,解方程可知答案为∑i=1n(scorei−90)9n+∑i=1n(scorei−90)\frac{\sum_{i=1}^n(score_i-90)}{9n+\sum_{i=1}^n(score_i-90)}9n+∑i=1n(scorei−90)∑i=1n(scorei−90)。
也可以使用二分求解。
#includeusing namespace std; int main(){ int n,sum=0,tp=0; cin>>n; for(int i=0;i >tp; sum+=tp; } double S = sum-90*n; cout<
匹配星星
这道题目可以使用贪心算法求解。先按照X坐标从小到大排序,然后对于每一个点
- 如果Z = 1,查询比他X坐标小的Y坐标最大的Z= 0的点,进行配对,如果配对成功则将那个点都从候选点中排除。
- 如果Z = 0,将该点加入候选点。
#include#include #include #include using namespace std; typedef long long ll; struct P{ int a,b,c; bool operator < (const P &rhs) const{ if(a == rhs.a)return c>rhs.c; return a >n; for(int i=0;i >alp[i].a>>alp[i].b>>alp[i].c; sort(alp,alp+n); multiset pool; multiset ::iterator it; int ans = 0; for(int i=0;i
H - 坐火车
线段树写的,我看出题人那个思维我还是不习惯,自己想了一个写法。
先用g统计1到n颜色的总数量,然后gg统计1到i-1的颜色数量,每次都只改变一个点,我们只需要更新这个点的颜色贡献,贡献值为res=1ll*(g[f[i].c]-1-gg[f[i].c])*gg[f[i].c]; 然后查询就好了。这题有点卡常,加了个ll rr就A了
#include#include #include #include #include #include #include #include #include #include