省选磨泥34
可能是时运不济,导致我菜到家了...
AK啊三个人,啊啊啊我只有一半的分
一眼切第一题,第二题整个人发憷,第三题想打部分分打完了发现假了...
T1 无向图
直接可撤销线性基,据说有直接撤销版本的单\(log\),我我是线段树分治
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1e5+5;
int m,q,ans[N];
struct BAS{
int lba[35],cba;
int ins(int x){
fu(i,30,0)if(x>>i&1){
if(lba[i])x^=lba[i];
else {
lba[i]=x;cba++;
return i;
}
}
return -1;
}
void ers(int x){if(x==-1)return ;lba[x]=0;cba--;}
}bas;
struct XDS{
#define ls x<<1
#define rs x<<1|1
vector<int> vec[N*4];
void ins(int x,int l,int r,int ql,int qr,int v){
if(ql<=l&&r<=qr)return vec[x].push_back(v),void();
int mid=l+r>>1;
if(ql<=mid)ins(ls,l,mid,ql,qr,v);
if(qr>mid)ins(rs,mid+1,r,ql,qr,v);
return ;
}
int sta[N],top;
void dfs(int x,int l,int r){
// cerr<<x<<" "<<l<<" "<<r<<" "<<bas.cba<<endl;
int s=top;
for(int i:vec[x])sta[++top]=bas.ins(i);
if(l==r){
ans[l]=(1<<bas.cba);
while(top>s)bas.ers(sta[top--]);
return ;
}
int mid=l+r>>1;
dfs(ls,l,mid);
dfs(rs,mid+1,r);
while(top>s)bas.ers(sta[top--]);
}
#undef ls
#undef rs
}xds;
map<int,int> mp;
signed main(){
freopen("xor.in","r",stdin);
freopen("xor.out","w",stdout);
m=read();q=read();
fo(i,1,q){
int tp=read(),x=read();
if(tp==1)mp[x]=i;
else xds.ins(1,1,q,mp[x],i-1,x),mp.erase(x);
}
for(pair<int,int> i:mp)xds.ins(1,1,q,i.second,q,i.first);
xds.dfs(1,1,q);
fo(i,1,q)printf("%d\n",ans[i]);
return 0;
}
T2 加与乘
A要是最后一手,那A必胜
如果B是最后一手的话,那么当A操作时如果两个相邻的偶数之间都有奇数个奇数,包括和开头和末尾,那A必输
那么如果是A先手直接判断就好了
如果是B先手,判断是不是只有一个区间是不合法的就好了
考场上看出来这个结论了,但是没有分A先手还是B先手,其实就是不会
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1e5+5;
int T,n[11],m[11],a[11][N];
int mx,dp[21][1<<20][2],sum[1<<20];
inline int get(int l,int r){return (1<<l+1)-(1<<r);}
void init_dp(){
dp[1][1][0]=dp[1][1][1]=1;
dp[1][0][0]=dp[1][0][1]=0;
fo(len,2,20)fo(s,0,(1<<len)-1){
fo(i,0,1){
bool flag=i^1;
fo(j,1,len-1){int t;
int t1=(s>>j)&1,t2=(s>>j-1)&1;
t=((s&get(len-1,j+1))>>1)|((t1&t2)<<j-1)|(s&get(j-2,0));
if(dp[len-1][t][i^1]==i)flag=i;
t=((s&get(len-1,j+1))>>1)|((t1^t2)<<j-1)|(s&get(j-2,0));
if(dp[len-1][t][i^1]==i)flag=i;
}
dp[len][s][i]=flag;
}
}
}
void spj(int id){int now=0;
fo(i,1,n[id])now=(now<<1)+a[id][i];
printf(dp[n[id]][now][m[id]]?"B\n":"A\n");
}
signed main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
T=read();bool fl=false;
fo(tt,1,T){
n[tt]=read();m[tt]=read();
fo(i,1,n[tt])a[tt][i]=read()&1;
if(n[tt]<=20)fl=true,mx=max(mx,n[tt]);
}
if(fl)init_dp();
fo(tt,1,T){
if(((n[tt]-1)&1)!=m[tt]){printf("A\n");continue;}
if(n[tt]<=20){spj(tt);continue;}
int las=0,sm=0;int flag=0;
fo(i,1,n[tt])if(!a[tt][i]){
if(i-las&1)flag++;
las=i;sm++;
}
if(n[tt]+1-las&1)flag++;
if(!m[tt])printf(!flag?"B\n":"A\n");
else if(m[tt])printf(flag==1?"B\n":"A\n");
}
return 0;
}
T3 数颜色
发现就是统计一个点被覆盖了但是他到他爹的边没有被覆盖的个数
于是我们分机器人考虑,一个机器人的贡献就是在lca处给出的
如果贡献不见了,那就是被其他的机器人路线给覆盖了
我们想要找前驱和后继,但是发现如果有两个一样的机器人,那就互相找不到了
于是我们让后面的可以找到前面的,就找前驱的时候覆盖lca,后继的时候就不覆盖了
AC_code
#include<bits/stdc++.h>
using namespace std;
#define fo(i,x,y) for(int i=(x);i<=(y);i++)
#define fu(i,x,y) for(int i=(x);i>=(y);i--)
int read(){
int s=0,t=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')t=-1;ch=getchar();}
while(isdigit(ch)){s=(s<<1)+(s<<3)+(ch^48);ch=getchar();}
return s*t;
}
const int N=1e5+5;
int n,m,q,ans[N];
struct A{int x,y,lca;}a[N];
struct B{int l,r,id;}b[N];
bool com(B a,B b){return a.l<b.l;}
struct E{int to,nxt;}e[N*2];
int head[N],rp;
void add_edg(int x,int y){e[++rp].to=y;e[rp].nxt=head[x];head[x]=rp;}
struct XDS{
#define ls x<<1
#define rs x<<1|1
int who[N*4],two[N*4];
void pushdown(int x){
who[ls]=two[ls]=two[x];
who[rs]=two[rs]=two[x];
two[x]=0;return ;
}
void build(int x,int l,int r){
who[x]=two[x]=0;
if(l==r)return ;
int mid=l+r>>1;
build(ls,l,mid);
build(rs,mid+1,r);
return ;
}
void ins(int x,int l,int r,int ql,int qr,int v){
if(ql>qr)return ;
if(ql<=l&&r<=qr)return who[x]=two[x]=v,void();
int mid=l+r>>1;if(two[x])pushdown(x);
if(ql<=mid)ins(ls,l,mid,ql,qr,v);
if(qr>mid)ins(rs,mid+1,r,ql,qr,v);
}
int query(int x,int l,int r,int pos){
if(l==r)return who[x];
int mid=l+r>>1;if(two[x])pushdown(x);
if(pos<=mid)return query(ls,l,mid,pos);
else return query(rs,mid+1,r,pos);
}
#undef ls
#undef rs
}xds;
int siz[N],son[N],top[N],dep[N],fa[N];
void dfs_fi(int x,int f){
fa[x]=f;dep[x]=dep[f]+1;
siz[x]=1;son[x]=0;
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==f)continue;
dfs_fi(y,x);siz[x]+=siz[y];
if(!son[x]||siz[y]>siz[son[x]])son[x]=y;
}
}
int dfn[N],idf[N],cnt;
void dfs_se(int x,int f){
top[x]=f;dfn[x]=++cnt;idf[cnt]=x;
if(son[x])dfs_se(son[x],f);
for(int i=head[x];i;i=e[i].nxt){
int y=e[i].to;
if(y==fa[x]||y==son[x])continue;
dfs_se(y,y);
}
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=fa[top[x]];
}return dep[x]<dep[y]?x:y;
}
void change1(int x,int y,int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
xds.ins(1,1,n,dfn[top[x]],dfn[x],v);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
xds.ins(1,1,n,dfn[x],dfn[y],v);
}
void change2(int x,int y,int v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
xds.ins(1,1,n,dfn[top[x]],dfn[x],v);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
xds.ins(1,1,n,dfn[x]+1,dfn[y],v);
}
int ll[N],rr[N];
struct BIT{
int tr[N];
void insert(int x,int v){
for(int i=x;i<=n;i+=(i&-i))tr[i]+=v;
}
int query(int x){
int ret=0;
for(int i=x;i;i-=(i&-i))ret+=tr[i];
return ret;
}
void ins(int l,int r,int v){
// cerr<<"ins"<<" "<<l<<" "<<r<<" "<<v<<endl;
insert(l,v);insert(r+1,-v);
}
}bit;
vector<int> del[N];
signed main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
n=read();m=read();q=read();
fo(i,1,n-1){
int x=read(),y=read();
add_edg(x,y);add_edg(y,x);
}
dfs_fi(1,0);dfs_se(1,1);
fo(i,1,m)a[i].x=read(),a[i].y=read(),a[i].lca=LCA(a[i].x,a[i].y);
fo(i,1,q)b[i].l=read(),b[i].r=read(),b[i].id=i;
fo(i,1,m){
ll[i]=xds.query(1,1,n,dfn[a[i].lca]);
change1(a[i].x,a[i].y,i);
}xds.build(1,1,n);
fu(i,m,1){
rr[i]=xds.query(1,1,n,dfn[a[i].lca]);
change2(a[i].x,a[i].y,i);
}
sort(b+1,b+q+1,com);b[q+1].l=m+1;
// fo(i,1,m)cerr<<ll[i]<<" "<<rr[i]<<endl;
fu(qq,q,1){
fu(i,b[qq+1].l-1,b[qq].l){
// cerr<<qq<<" "<<i<<" "<<b[qq].l<<endl;
for(int x:del[i]){
if(rr[x])bit.ins(x,rr[x]-1,-1);
else bit.ins(x,n,-1);
}
if(rr[i])bit.ins(i,rr[i]-1,1);
else bit.ins(i,n,1);
if(ll[i])del[ll[i]].push_back(i);
}
// cerr<<"ans"<<" "<<b[qq].id<<" "<<b[qq].l<<" "<<b[qq].r<<" "<<bit.query(b[qq].r)<<endl;
ans[b[qq].id]=bit.query(b[qq].r);
}
fo(i,1,q)printf("%d\n",ans[i]);
}
QQ:2953174821