[考试反思]0405省选模拟63:顽固
总得分总算有一次是青绿色的了。。。橙红习惯了得到这种颜色就很满足。。
T1依旧比较送分,但是还是做的有点慢,其实不难但是有点墨迹了,半数的人$AC$了。
耽误了不少时间之后开始看$T2,3$发现$T3$是个神奇的博弈,大约可以找找规律打打表。
至少$50$已经到手了,估计$70$也不难,可能能冲正解。
$T2$看起来像个大字符串,暴力的$25pts$也许比较简单。
于是打算按顺序,先写暴力。结果就到十一点半了。
大样例死活过不去,小数据死活不出错,然后我就结束了。
最后匆匆忙忙把$T3$白送的分拿走,就结束了。。。
结果$T2$的暴力是挂了一个小细节,$T3$是结论。。。
就这样吧。
T1:大佬的难题
大意:给定三个排列求$\sum\limits_{1 \le i,j \le n}[A_i < A_j][B_i<B_j][C_i<C_j]$
容斥。所有的减去满足其中一条的加上满足两条的。最后这个用树状数组就行。最后再除以二什么的。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define S 2000005 4 int t1[S],t2[S],t3[S],n,a[S],b[S],c[S],seed,pa[S],pb[S];long long ans; 5 void add1(int p){for(;p<=n;p+=p&-p)t1[p]++;} 6 void ask1(int p,int a=0){for(;p;p^=p&-p)ans+=t1[p];} 7 void add2(int p){for(;p<=n;p+=p&-p)t2[p]++;} 8 void ask2(int p,int a=0){for(;p;p^=p&-p)ans+=t2[p];} 9 void add3(int p){for(;p<=n;p+=p&-p)t3[p]++;} 10 void ask3(int p,int a=0){for(;p;p^=p&-p)ans+=t3[p];} 11 int main(){ 12 cin>>n; ans=-n*(n-1ll)/2; 13 for(int i=1;i<=n;++i)a[i]=b[i]=c[i]=i; 14 cin>>seed; for(int i=1;i<=n;++i)seed=(1ll*seed*19260817^233333)&16777215,swap(a[i],a[seed%i+1]); 15 cin>>seed; for(int i=1;i<=n;++i)seed=(1ll*seed*19260817^233333)&16777215,swap(b[i],b[seed%i+1]); 16 cin>>seed; for(int i=1;i<=n;++i)seed=(1ll*seed*19260817^233333)&16777215,swap(c[i],c[seed%i+1]); 17 for(int i=1;i<=n;++i)pa[a[i]]=pb[b[i]]=i; 18 for(int i=1;i<=n;++i)ask1(b[pa[i]]),ask2(c[pa[i]]),ask3(c[pb[i]]),add1(b[pa[i]]),add2(c[pa[i]]),add3(c[pb[i]]); 19 cout<<ans/2<<endl; 20 }
T2:回文串
大意:维护字符串,支持:在左或右插入字符,求两个子串的$ \ge lcp/lcs$长度的$prefix/suffix$的回文串在整个字符串中出现次数求和。$n,q \le 10^5$
代码太恶心,先放放。
需要记住的思路之一,就是这种前后都要加字符的题,看似不可做,然而如果没有强制在线的话可以把整个串都离线建出来再预处理。
这道题要求的大概就是$PAM$的$fail$树上两个点之间的路径的$size \times length$之和。
因为有加入字符所以需要用数据结构维护,$lct$或树链剖分皆可。
时间复杂度是$O(n+qlogn)$的
T3:营养餐
大意:博弈,树上每个点有$A_i$个石子,要求时刻满足$A_i \ge \sum\limits_{j \in son(i)} A_j \times B_j$。每次操作可以在一个点取走若干石子。$n \le 10^5$
重新定义$C_i = A_i -\sum\limits_{j \in son(i)} A_j \times B_j$。游戏规则变为每个节点最开始有$C_i \ge 0$个石子。
每次操作$i$节点拿走$j$石子时,$fa(j)$都会增加$B_ix$个石子。直接就是阶梯$nim$
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define S 111111 4 int n,a[S],b[S],l[S],ec,fir[S],to[S],dep[S],ful[S],f[S],ans; 5 void link(int a,int b){l[++ec]=fir[a];fir[a]=ec;to[ec]=b;} 6 void dfs(int p,int fa){ 7 dep[p]=b[p]?dep[fa]+1:1; int z=a[p]; 8 for(int i=fir[p];i;i=l[i])if(to[i]!=fa)dfs(to[i],p),z-=a[to[i]]*b[to[i]]; 9 if(dep[p]&1)ans^=z; 10 } 11 int main(){int t;cin>>t;while(t--){ 12 cin>>n;ans=0; 13 for(int i=1;i<=n;++i)scanf("%d",&a[i]); 14 for(int i=1;i<=n;++i)scanf("%d",&b[i]); 15 for(int i=1,x,y;i<n;++i)scanf("%d%d",&x,&y),link(x,y),link(y,x); 16 dfs(1,0); puts(ans?"YES":"NO"); 17 memset(fir,0,sizeof fir);ec=0; 18 }}