大模拟代码记录
CSP 赛事以为我能 30 分钟写出来 T3 于是我最后 30 分钟开始写 T3 然后没写完。然后 CSP 结束之后立刻开始做大模拟题。
删除了所有调试信息和注释。
P9754 [CSP-S 2023] 结构体
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+50;
int N;
string s,t,Na;
int CntStruct;
string NaYuan[205],NaSon[205][205];
map<string,int>StructId,SonId[205],Yuan;
int Cnt[MAXN];
struct Dot
{
int Id1;
long long a,s,Pos;
Dot(int _Id1,long long _a,long long _s,long long _Pos)
{
Id1=_Id1;
a=_a;
s=_s;
Pos=_Pos;
}
};
vector<Dot>Son[MAXN];
long long Len[MAXN],Size[MAXN];
long long ALLBegin;
long long sYuan[MAXN],aYuan[MAXN],tYuan[MAXN];
int CntYuan;
long long ans[MAXN];
int main()
{
StructId["byte"]=1;
Len[1]=Size[1]=1;
StructId["short"]=2;
Len[2]=Size[2]=2;
StructId["int"]=3;
Len[3]=Size[3]=4;
StructId["long"]=4;
Len[4]=Size[4]=8;
CntStruct=4;
cin>>N;
ALLBegin=0;
while(N--)
{
int op;
cin>>op;
if(op==1)
{
cin>>s;
StructId[s]=++CntStruct;
cin>>Cnt[CntStruct];
long long Begin=0;
for(int i=1;i<=Cnt[CntStruct];i++)
{
cin>>t>>Na;
NaSon[CntStruct][i-1]=Na;
if(i>1)
Begin=((Begin+Son[CntStruct].back().s-1)/Len[StructId[t]]+1)*Len[StructId[t]];
Son[CntStruct].push_back(Dot(StructId[t],Len[StructId[t]],Size[StructId[t]],Begin));
SonId[CntStruct][Na]=i-1;
Len[CntStruct]=max(Len[CntStruct],Len[StructId[t]]);
}
Size[CntStruct]=((Begin+Son[CntStruct].back().s-1)/Len[CntStruct]+1)*Len[CntStruct];
cout<<Size[CntStruct]<<" "<<Len[CntStruct]<<endl;
}
if(op==2)
{
cin>>t>>Na;
CntYuan++;
NaYuan[CntYuan]=Na;
Yuan[Na]=CntYuan;
tYuan[CntYuan]=StructId[t];
aYuan[CntYuan]=Len[tYuan[CntYuan]];
sYuan[CntYuan]=Size[tYuan[CntYuan]];
if(CntYuan>1)
{
ALLBegin=((ALLBegin+sYuan[CntYuan-1]-1)/aYuan[CntYuan]+1)*aYuan[CntYuan];
}
cout<<ALLBegin<<endl;
ans[CntYuan]=ALLBegin;
}
if(op==3)
{
cin>>s;
int NowId=0;
bool flag=false;
long long NowPos;
Na.clear();
for(int i=0;i<=s.length();i++)
{
if(i==s.length()||s[i]=='.')
{
if(flag==false)
{
NowId=Yuan[Na];
flag=true;
NowPos=ans[NowId];
NowId=tYuan[NowId];
}
else
{
int IdSon=SonId[NowId][Na];
Dot NowSon=Son[NowId][IdSon];
NowPos+=NowSon.Pos;
NowId=NowSon.Id1;
}
Na.clear();
}
else
{
Na.push_back(s[i]);
}
}
cout<<NowPos<<endl;
}
if(op==4)
{
long long NowPos;
cin>>NowPos;
int YuanId=0;
for(int i=1;i<=CntYuan;i++)
{
if(ans[i]>NowPos)
{
YuanId=i-1;
NowPos-=ans[i-1];
break;
}
}
if(YuanId==0)
{
YuanId=CntYuan;
NowPos-=ans[CntYuan];
}
string Nowans;
Nowans+=NaYuan[YuanId];
int ZiId=tYuan[YuanId];
bool flag=false;
while(true)
{
if(ZiId<=4)
{
if(NowPos>=0&&NowPos<Size[ZiId])
break;
}
if(NowPos>=Size[ZiId])
{
flag=true;
break;
}
bool Cut=false;
for(int i=0;i<Son[ZiId].size();i++)
{
if(Son[ZiId][i].Pos>NowPos)
{
Cut=true;
NowPos-=Son[ZiId][i-1].Pos;
Nowans+=".";
Nowans+=NaSon[ZiId][i-1];
ZiId=Son[ZiId][i-1].Id1;
break;
}
}
if(Cut==false)
{
NowPos-=Son[ZiId].back().Pos;
Nowans+=".";
Nowans+=NaSon[ZiId][Cnt[ZiId]-1];
ZiId=Son[ZiId].back().Id1;
}
}
if(flag)
puts("ERR");
else
cout<<Nowans<<endl;
}
}
}
P8216 [THUPC2022 初赛] 画图
#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+50;
int N;
struct Line
{
int op,l,r,a;
Line(){}
Line(int _op,int _l,int _r,int _a)
{
op=_op;
l=_l;
r=_r;
a=_a;
}
}d[MAXN];
bool cmp1(Line a,Line b)
{
return a.a<b.a;
}
bool cmp2(Line a,Line b)
{
if(a.l==b.l)
return a.r>b.r;
return a.l<b.l;
}
int tot;
int G;
vector<Line>Vec[2],Temp,Group[20];
bool XiangJiao(Line a,Line b)
{
if(a.op==b.op)
{
return false;
}
if(b.l<=a.a&&a.a<=b.r&&a.l<=b.a&&b.a<=a.r)
return true;
return false;
}
void Read()
{
scanf("%d",&N);
for(int i=1;i<=N;i++)
{
int op,l,r,a;
scanf("%d%d%d%d",&op,&l,&r,&a);
Vec[op].push_back(Line(op,l,r,a));
}
}
void MergeSolve()
{
sort(Temp.begin(),Temp.end(),cmp2);
int Nowl=Temp[0].l,Nowr=Temp[0].r;
for(int i=1;i<Temp.size();i++)
{
if(Temp[i].l>Nowr)
{
d[++tot]=Line(Temp[0].op,Nowl,Nowr,Temp[0].a);
Nowl=Temp[i].l;
Nowr=Temp[i].r;
}
else
{
Nowr=max(Nowr,Temp[i].r);
}
}
d[++tot]=Line(Temp[0].op,Nowl,Nowr,Temp[0].a);
}
void Merge(int op)
{
sort(Vec[op].begin(),Vec[op].end(),cmp1);
for(int i=0;i<Vec[op].size();i++)
{
int j=i;
Temp.clear();
Temp.push_back(Vec[op][i]);
while(j+1<Vec[op].size()&&Vec[op][j+1].a==Vec[op][i].a)
{
j++;
Temp.push_back(Vec[op][j]);
}
MergeSolve();
i=j;
}
}
bool Check1()
{
if(tot!=15)
return false;
int Cnt=0;
for(int i=1;i<=tot;i++)
{
Cnt+=d[i].op;
}
if(Cnt!=8)
return false;
return true;
}
int father[MAXN];
int getfather(int x)
{
if(x!=father[x])
father[x]=getfather(father[x]);
return father[x];
}
bool vis[MAXN];
void Merge2()
{
for(int i=1;i<=tot;i++)
{
father[i]=i;
}
for(int Id=1;Id<=tot;Id++)
{
for(int i=1;i<=tot;i++)
{
if(i==Id)
continue;
if(XiangJiao(d[i],d[Id]))
{
int fx=getfather(i),fy=getfather(Id);
if(fx!=fy)
father[fy]=fx;
}
}
}
for(int i=1;i<=tot;i++)
{
bool flag=false;
for(int j=1;j<=tot;j++)
{
if(flag==false&&getfather(j)==i)
{
flag=true;
G++;
}
if(getfather(j)==i)
{
Group[G].push_back(d[j]);
}
}
}
}
int Id[10];
int Id2[10];
bool CheckT(vector<Line>Now)
{
if(Now.size()!=2)
return false;
for(int i=1;i<=2;i++)
Id2[i]=i;
while(true)
{
int I1=Id2[1]-1,I2=Id2[2]-1;
if(Now[I1].op==0
&&Now[I2].op==1
&&Now[I2].l<Now[I1].a
&&Now[I1].a==Now[I2].r
&&Now[I1].l<Now[I2].a
&&Now[I1].r>Now[I2].a
)
return true;
if(next_permutation(Id2+1,Id2+3)==false)
break;
}
return false;
}
bool CheckH(vector<Line>Now)
{
if(Now.size()!=3)
return false;
for(int i=1;i<=3;i++)
Id2[i]=i;
while(true)
{
int I3=Id2[1]-1,I4=Id2[2]-1,I5=Id2[3]-1;
if(Now[I3].op==1
&&Now[I4].op==0
&&Now[I5].op==1
&&Now[I3].l==Now[I5].l
&&Now[I5].l<Now[I4].a
&&Now[I4].a<Now[I3].r
&&Now[I3].r==Now[I5].r
&&Now[I3].a==Now[I4].l
&&Now[I4].l<Now[I4].r
&&Now[I4].r==Now[I5].a
)
return true;
if(next_permutation(Id2+1,Id2+4)==false)
break;
}
return false;
}
bool CheckU(vector<Line>Now)
{
if(Now.size()!=3)
return false;
for(int i=1;i<=3;i++)
Id2[i]=i;
while(true)
{
int I6=Id2[1]-1,I7=Id2[2]-1,I8=Id2[3]-1;
if(Now[I6].op==1
&&Now[I7].op==0
&&Now[I8].op==1
&&Now[I6].l==Now[I8].l
&&Now[I8].l==Now[I7].a
&&Now[I7].a<Now[I6].r
&&Now[I6].r==Now[I8].r
&&Now[I6].a==Now[I7].l
&&Now[I7].l<Now[I7].r
&&Now[I7].r==Now[I8].a
)
return true;
if(next_permutation(Id2+1,Id2+4)==false)
break;
}
return false;
}
bool CheckP(vector<Line>Now)
{
if(Now.size()!=4)
return false;
for(int i=1;i<=4;i++)
Id2[i]=i;
while(true)
{
int I9=Id2[1]-1,I10=Id2[2]-1,I11=Id2[3]-1,I12=Id2[4]-1;
if(Now[I9].op==1
&&Now[I10].op==0
&&Now[I11].op==0
&&Now[I12].op==1
&&Now[I9].l<Now[I11].a
&&Now[I11].a==Now[I12].l
&&Now[I12].l<Now[I9].r
&&Now[I9].r==Now[I10].a
&&Now[I10].a==Now[I12].r
&&Now[I9].a==Now[I10].l
&&Now[I10].l==Now[I11].l
&&Now[I11].l<Now[I10].r
&&Now[I10].r==Now[I11].r
&&Now[I11].r==Now[I12].a
)
return true;
if(next_permutation(Id2+1,Id2+5)==false)
break;
}
return false;
}
bool CheckC(vector<Line>Now)
{
if(Now.size()!=3)
return false;
for(int i=1;i<=3;i++)
Id2[i]=i;
while(true)
{
int I13=Id2[1]-1,I14=Id2[2]-1,I15=Id2[3]-1;
if(Now[I13].op==1
&&Now[I14].op==0
&&Now[I15].op==0
&&Now[I13].l==Now[I15].a
&&Now[I15].a<Now[I13].r
&&Now[I13].r==Now[I14].a
&&Now[I13].a==Now[I14].l
&&Now[I14].l==Now[I15].l
&&Now[I15].l<Now[I14].r
&&Now[I14].r==Now[I15].r
)
return true;
if(next_permutation(Id2+1,Id2+4)==false)
break;
}
return false;
}
bool Check3()
{
if(CheckT(Group[Id[1]])
&&CheckH(Group[Id[2]])
&&CheckU(Group[Id[3]])
&&CheckP(Group[Id[4]])
&&CheckC(Group[Id[5]])
)
return true;
return false;
}
int main()
{
Read();
Merge(0);
Merge(1);
if(Check1()==false)
{
puts("No");
return 0;
}
Merge2();
if(G>=6)
{
puts("No");
return 0;
}
for(int i=1;i<=5;i++)
{
Id[i]=i;
}
while(true)
{
if(Check3())
{
puts("Yes");
return 0;
}
if(next_permutation(Id+1,Id+6)==false)
break;
}
puts("No");
}
P3952 [NOIP2017 提高组] 时间复杂度
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+50;
int L;
char O[MAXN];
int wO,LenO;
bool O1;
bool Use[MAXN];
int sta[MAXN],Top;
int Nowfather,father[MAXN];
char ch[MAXN],Nowch[20];
int Cnt;
int f[MAXN];
struct Edge
{
int x,y,Next;
}e[MAXN<<1];
int elast[MAXN],tot;
void Add(int x,int y)
{
tot++;
e[tot].x=x;
e[tot].y=y;
e[tot].Next=elast[x];
elast[x]=tot;
}
int Max;
int depth[MAXN];
void dfs(int u,int fa)
{
if(f[u]==-1)
return;
depth[u]=depth[fa]+f[u];
Max=max(Max,depth[u]);
for(int i=elast[u];i;i=e[i].Next)
{
int v=e[i].y;
if(v==fa)
continue;
dfs(v,u);
}
}
void Clear()
{
Top=tot=Cnt=Nowfather=0;
wO=LenO=O1=0;
for(int i=0;i<=100;i++)
{
f[i]=elast[i]=father[i]=depth[i]=0;
}
for(int i='a';i<='z';i++)
{
Use[i]=false;
}
}
char op[30],opx[30],opy[30];
int Lenx,Leny,Numx,Numy;
void Solve()
{
Clear();
scanf("%d%s",&L,&O[1]);
LenO=strlen(O+1);
if(O[3]=='1')
{
O1=true;
}
else
{
O1=false;
for(int i=5;;i++)
{
if(O[i]==')')
break;
wO=wO*10+O[i]-48;
}
}
bool flag=false;
while(L--)
{
scanf("%s",&op[1]);
if(op[1]=='F')
{
scanf("%s",&Nowch[1]);
scanf("%s%s",&opx[1],&opy[1]);
if(flag)
continue;
if(Use[Nowch[1]])
{
flag=true;
continue;
}
Use[Nowch[1]]=true;
Cnt++;
ch[Cnt]=Nowch[1];
sta[++Top]=Cnt;
father[Cnt]=Nowfather;
Nowfather=Cnt;
Lenx=strlen(opx+1);
Leny=strlen(opy+1);
if(opx[1]=='n'||opy[1]=='n')
{
if(opx[1]=='n'&&opy[1]=='n')
{
f[Cnt]=0;
}
else
{
if(opx[1]=='n')
{
f[Cnt]=-1;
}
if(opy[1]=='n')
{
f[Cnt]=1;
}
}
}
else
{
Numx=Numy=0;
for(int i=1;i<=Lenx;i++)
{
Numx=Numx*10+opx[i]-48;
}
for(int i=1;i<=Leny;i++)
{
Numy=Numy*10+opy[i]-48;
}
if(Numx<=Numy)
{
f[Cnt]=0;
}
else
{
f[Cnt]=-1;
}
}
}
else
{
if(flag)
continue;
if(Top==0)
{
flag=true;
continue;
}
Use[ch[Nowfather]]=false;
Top--;
Nowfather=father[Nowfather];
}
}
if(flag||Top!=0)
{
puts("ERR");
return;
}
for(int i=1;i<=Cnt;i++)
{
Add(father[i],i);
}
Max=0;
dfs(0,0);
if(O1)
{
if(Max==0)
puts("Yes");
else
puts("No");
}
else
{
if(Max!=wO)
puts("No");
else
puts("Yes");
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
Solve();
}
}
P3341 [ZJOI2014] 消棋子
#include <bits/stdc++.h>
using namespace std;
static char buf[1000000],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
template<typename item>
inline void read(register item &x)
{
bool flag=false;
x=0;register char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
flag=true;
c=getchar();
}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(flag)
x=-x;
}
const int MAXN=1e5+50;
int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
struct Dot
{
int x,y,Color,a;
Dot(){}
Dot(int _x,int _y,int _Color,int _a)
{
x=_x;
y=_y;
Color=_Color;
a=_a;
}
}Son[MAXN][2];
bool operator <(Dot a,Dot b)
{
if(a.a==b.a)
{
return a.x<b.x;
}
return a.a<b.a;
}
set<Dot>Hang[MAXN],Lie[MAXN];
bool Have(int x,int y)
{
set<Dot>::iterator it=Lie[y].lower_bound(Dot(0,0,0,x));
if(it==Lie[y].end())
return false;
if((*it).x==x&&(*it).y==y)
return true;
return false;
}
Dot Find(int x,int y,int op)
{
Dot Now=Dot(-1,-1,-1,-1);
set<Dot>::iterator it;
if(op==1)
{
it=Lie[y].upper_bound(Dot(0,0,0,x));
if(it==Lie[y].begin())
return Now;
it--;
return *it;
}
if(op==2)
{
it=Lie[y].lower_bound(Dot(0,0,0,x));
if(it==Lie[y].end())
return Now;
return *it;
}
if(op==3)
{
it=Hang[x].upper_bound(Dot(0,0,0,y));
if(it==Hang[x].begin())
return Now;
it--;
return *it;
}
if(op==4)
{
it=Hang[x].lower_bound(Dot(0,0,0,y));
if(it==Hang[x].end())
return Now;
return *it;
}
return Now;
}
void Del(Dot Now)
{
Now.a=Now.x;
Lie[Now.y].erase(Now);
Now.a=Now.y;
Hang[Now.x].erase(Now);
}
bool Same(Dot a,Dot b)
{
if(a.x==b.x&&a.y==b.y)
return true;
return false;
}
bool Check(int Color)
{
int sx1=Son[Color][0].x,sy1=Son[Color][0].y,sx2=Son[Color][1].x,sy2=Son[Color][1].y;
if(sx1==sx2)
{
if(sy1+1==sy2)
return false;
if(Same(Son[Color][1],Find(sx1,sy1+1,4)))
return true;
return false;
}
if(sy1==sy2)
{
if(sx1+1==sx2)
return false;
if(Same(Son[Color][1],Find(sx1+1,sy1,2)))
return true;
return false;
}
if(sy2<sy1)
{
if(Have(sx1,sy2)==false&&Same(Find(sx1,sy2,4),Son[Color][0])&&Same(Find(sx1,sy2,2),Son[Color][1]))
return true;
if(Have(sx2,sy1)==false&&Same(Find(sx2,sy1,1),Son[Color][0])&&Same(Find(sx2,sy1,3),Son[Color][1]))
return true;
return false;
}
else
{
if(Have(sx1,sy2)==false&&Same(Find(sx1,sy2,3),Son[Color][0])&&Same(Find(sx1,sy2,2),Son[Color][1]))
return true;
if(Have(sx2,sy1)==false&&Same(Find(sx2,sy1,1),Son[Color][0])&&Same(Find(sx2,sy1,4),Son[Color][1]))
return true;
return false;
}
return false;
}
int R,C,N;
queue<int>q;
int Use[MAXN],UseColor;
bool Inq[MAXN];
int main()
{
read(R);
read(C);
read(N);
for(int i=1;i<=N;i++)
{
read(Son[i][0].x);
read(Son[i][0].y);
read(Son[i][1].x);
read(Son[i][1].y);
Son[i][0].Color=Son[i][1].Color=i;
if(Son[i][0].x>Son[i][1].x)
{
swap(Son[i][0],Son[i][1]);
}
if(Son[i][0].x==Son[i][1].x&&Son[i][0].y>Son[i][1].y)
{
swap(Son[i][0],Son[i][1]);
}
Dot Now;
for(int op=0;op<=1;op++)
{
Now=Son[i][op];
Now.a=Now.y;
Hang[Now.x].insert(Now);
Now.a=Now.x;
Lie[Now.y].insert(Now);
}
}
int Q,ans1=0;
read(Q);
while(Q--)
{
int x,y;
char op1[2],op2[2];
read(x);
read(y);
op1[0]=getchar();
while(op1[0]==' '||op1[0]=='\n')
op1[0]=getchar();
op2[0]=getchar();
while(op2[0]==' '||op2[0]=='\n')
op2[0]=getchar();
if(Have(x,y))
{
continue;
}
Dot Now1,Now2;
if(op1[0]=='U')
{
Now1=Find(x,y,1);
}
if(op1[0]=='D')
{
Now1=Find(x,y,2);
}
if(op1[0]=='L')
{
Now1=Find(x,y,3);
}
if(op1[0]=='R')
{
Now1=Find(x,y,4);
}
if(Now1.Color==-1)
continue;
if(op2[0]=='U')
{
Now2=Find(x,y,1);
}
if(op2[0]=='D')
{
Now2=Find(x,y,2);
}
if(op2[0]=='L')
{
Now2=Find(x,y,3);
}
if(op2[0]=='R')
{
Now2=Find(x,y,4);
}
if(Now2.Color==-1)
continue;
if(Now1.Color==Now2.Color)
{
Del(Now1);
Del(Now2);
ans1++;
}
}
for(int i=1;i<=R;i++)
{
Hang[i].clear();
}
for(int i=1;i<=C;i++)
{
Lie[i].clear();
}
for(int i=1;i<=N;i++)
{
Dot Now;
for(int op=0;op<=1;op++)
{
Now=Son[i][op];
Now.a=Now.y;
Hang[Now.x].insert(Now);
Now.a=Now.x;
Lie[Now.y].insert(Now);
}
}
cout<<ans1<<" ";
int ans2=0;
for(int i=1;i<=N;i++)
{
if(Check(i))
{
q.push(i);
Inq[i]=true;
}
}
while(!q.empty())
{
int Id=q.front();
q.pop();
ans2++;
Del(Son[Id][0]);
Del(Son[Id][1]);
UseColor++;
for(int op1=0;op1<=1;op1++)
{
for(int op2=1;op2<=4;op2++)
{
Dot Now=Find(Son[Id][op1].x,Son[Id][op1].y,op2);
if(Now.Color!=-1)
{
if(Inq[Now.Color]==false&&Use[Now.Color]!=UseColor)
{
Use[Now.Color]=UseColor;
if(Check(Now.Color))
{
q.push(Now.Color);
Inq[Now.Color]=true;
}
}
}
}
}
}
cout<<ans2;
}
P6916 [ICPC2015 WF] Window Manager
#include <bits/stdc++.h>
using namespace std;
const int MAXN=305;
int R,C;
char op[20];
int QId;
struct Square
{
int xl,yl;
int xr,yr;
int Time;
Square(){}
Square(int _xl,int _yl,int _xr,int _yr,int _Time)
{
xl=_xl;
yl=_yl;
xr=_xr;
yr=_yr;
Time=_Time;
}
}d[MAXN];
int N;
bool cmp(Square a,Square b)
{
return a.Time<b.Time;
}
bool cmp1(Square a,Square b)
{
return a.xl<b.xl;
}
bool cmp2(Square a,Square b)
{
return a.xl>b.xl;
}
bool cmp3(Square a,Square b)
{
return a.yl<b.yl;
}
bool cmp4(Square a,Square b)
{
return a.yl>b.yl;
}
bool In(int x,int y,Square b)
{
if(x<=b.xr&&y<=b.yr&&x>=b.xl&&y>=b.yl)
return true;
return false;
}
bool Bing(int l,int r,int ll,int rr)
{
if(l>ll)
{
swap(l,ll);
swap(r,rr);
}
if(ll<=r)
return true;
return false;
}
bool Jiao(Square a,Square b)
{
if(Bing(a.xl,a.xr,b.xl,b.xr)&&Bing(a.yl,a.yr,b.yl,b.yr))
return true;
return false;
}
int Getw(Square a)
{
return a.yr-a.yl+1;
}
int Geth(Square a)
{
return a.xr-a.xl+1;
}
vector<int>NewId;
bool Del[MAXN];
int main()
{
scanf("%d%d",&C,&R);
C--;
R--;
while(scanf("%s",&op[1])!=EOF)
{
QId++;
int x,y,w,h,dx,dy;
if(op[1]=='O')
{
scanf("%d%d%d%d",&y,&x,&w,&h);
Square Now=Square(x,y,x+h-1,y+w-1,QId);
bool flag=false;
for(int i=1;i<=N;i++)
{
if(Jiao(Now,d[i]))
{
flag=true;
break;
}
}
if(Now.xr>R||Now.yr>C)
flag=true;
if(flag)
{
printf("Command %d: OPEN - window does not fit\n",QId);
}
else
{
d[++N]=Now;
}
}
if(op[1]=='C')
{
scanf("%d%d",&y,&x);
bool flag=false;
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
N--;
for(int j=i;j<=N;j++)
{
d[j]=d[j+1];
}
break;
}
}
if(flag==false)
{
printf("Command %d: CLOSE - no window at given position\n",QId);
}
}
if(op[1]=='R')
{
scanf("%d%d%d%d",&y,&x,&w,&h);
bool flag=false;
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
Square Now=d[i];
Now.xr=Now.xl+h-1;
Now.yr=Now.yl+w-1;
bool flag2=false;
for(int j=1;j<=N;j++)
{
if(i==j)
continue;
if(Jiao(Now,d[j]))
{
flag2=true;
break;
}
}
if(Now.xr>R||Now.yr>C)
flag2=true;
if(flag2==false)
{
d[i]=Now;
break;
}
else
{
printf("Command %d: RESIZE - window does not fit\n",QId);
}
break;
}
}
if(flag==false)
{
printf("Command %d: RESIZE - no window at given position\n",QId);
}
}
if(op[1]=='M')
{
scanf("%d%d%d%d",&y,&x,&dy,&dx);
if(dx==0&&dy==0)
continue;
bool flag=false;
if(dy==0)
{
if(dx>0)
{
for(int i=1;i<=QId;i++)
Del[i]=false;
NewId.clear();
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
NewId.push_back(i);
Del[i]=true;
break;
}
}
if(flag==false)
{
printf("Command %d: MOVE - no window at given position\n",QId);
continue;
}
int Sum=dx;
while(true)
{
bool Full=false;
for(int i=0;i<NewId.size();i++)
{
if(d[NewId[i]].xr==R)
{
Full=true;
break;
}
}
if(Full)
break;
int MinId=-1,Min=1e9+1;
for(int i=0;i<NewId.size();i++)
{
Square Now=d[NewId[i]];
for(int j=1;j<=N;j++)
{
if(Del[j])
continue;
if(Bing(Now.yl,Now.yr,d[j].yl,d[j].yr)==false)
continue;
if(Now.xr>d[j].xl)
continue;
if(Min>d[j].xl-Now.xr-1)
{
Min=d[j].xl-Now.xr-1;
MinId=j;
}
}
}
for(int i=0;i<NewId.size();i++)
{
if(Min>=R-d[NewId[i]].xr)
{
Min=R-d[NewId[i]].xr;
MinId=-1;
}
}
if(MinId==-1||Min>Sum)
{
if(Min>=Sum)
{
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl+=Sum;
d[NewId[i]].xr+=Sum;
}
Sum=0;
}
else
{
Sum-=Min;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl+=Min;
d[NewId[i]].xr+=Min;
}
}
break;
}
else
{
Sum-=Min;
Del[MinId]=true;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl+=Min;
d[NewId[i]].xr+=Min;
}
NewId.push_back(MinId);
}
}
if(Sum>0)
{
printf("Command %d: MOVE - moved %d instead of %d\n",QId,dx-Sum,dx);
}
}
else
{
dx=-dx;
for(int i=1;i<=QId;i++)
Del[i]=false;
NewId.clear();
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
NewId.push_back(i);
Del[i]=true;
break;
}
}
if(flag==false)
{
printf("Command %d: MOVE - no window at given position\n",QId);
continue;
}
int Sum=dx;
while(true)
{
bool Full=false;
for(int i=0;i<NewId.size();i++)
{
if(d[NewId[i]].xl==0)
{
Full=true;
break;
}
}
if(Full)
break;
int MinId=-1,Min=1e9+1;
for(int i=0;i<NewId.size();i++)
{
Square Now=d[NewId[i]];
for(int j=1;j<=N;j++)
{
if(Del[j])
continue;
if(Now.xl<d[j].xr)
continue;
if(Bing(Now.yl,Now.yr,d[j].yl,d[j].yr)==false)
continue;
if(Min>Now.xl-d[j].xr-1)
{
Min=Now.xl-d[j].xr-1;
MinId=j;
}
}
}
for(int i=0;i<NewId.size();i++)
{
if(Min>=d[NewId[i]].xl)
{
Min=d[NewId[i]].xl;
MinId=-1;
}
}
if(MinId==-1||Min>=Sum)
{
if(Min>=Sum)
{
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl-=Sum;
d[NewId[i]].xr-=Sum;
}
Sum=0;
}
else
{
Sum-=Min;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl-=Min;
d[NewId[i]].xr-=Min;
}
}
break;
}
else
{
Sum-=Min;
Del[MinId]=true;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].xl-=Min;
d[NewId[i]].xr-=Min;
}
NewId.push_back(MinId);
}
}
if(Sum>0)
{
printf("Command %d: MOVE - moved %d instead of %d\n",QId,dx-Sum,dx);
}
}
}
else
{
if(dy>0)
{
for(int i=1;i<=QId;i++)
Del[i]=false;
NewId.clear();
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
NewId.push_back(i);
Del[i]=true;
break;
}
}
if(flag==false)
{
printf("Command %d: MOVE - no window at given position\n",QId);
continue;
}
int Sum=dy;
while(true)
{
bool Full=false;
for(int i=0;i<NewId.size();i++)
{
if(d[NewId[i]].yr==C)
{
Full=true;
break;
}
}
if(Full)
break;
int MinId=-1,Min=1e9+1;
for(int i=0;i<NewId.size();i++)
{
Square Now=d[NewId[i]];
for(int j=1;j<=N;j++)
{
if(Del[j])
continue;
if(Bing(Now.xl,Now.xr,d[j].xl,d[j].xr)==false)
continue;
if(Now.yr>d[j].yl)
continue;
if(Min>d[j].yl-Now.yr-1)
{
Min=d[j].yl-Now.yr-1;
MinId=j;
}
}
}
for(int i=0;i<NewId.size();i++)
{
if(C-d[NewId[i]].yr<=Min)
{
Min=C-d[NewId[i]].yr;
MinId=-1;
}
}
if(MinId==-1||Min>=Sum)
{
if(Min>=Sum)
{
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl+=Sum;
d[NewId[i]].yr+=Sum;
}
Sum=0;
}
else
{
Sum-=Min;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl+=Min;
d[NewId[i]].yr+=Min;
}
}
break;
}
else
{
Sum-=Min;
Del[MinId]=true;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl+=Min;
d[NewId[i]].yr+=Min;
}
NewId.push_back(MinId);
}
}
if(Sum>0)
{
printf("Command %d: MOVE - moved %d instead of %d\n",QId,dy-Sum,dy);
}
}
else
{
dy=-dy;
for(int i=1;i<=QId;i++)
Del[i]=false;
NewId.clear();
for(int i=1;i<=N;i++)
{
if(In(x,y,d[i]))
{
flag=true;
NewId.push_back(i);
Del[i]=true;
break;
}
}
if(flag==false)
{
printf("Command %d: MOVE - no window at given position\n",QId);
continue;
}
int Sum=dy;
while(true)
{
bool Full=false;
for(int i=0;i<NewId.size();i++)
{
if(d[NewId[i]].yl==0)
{
Full=true;
break;
}
}
if(Full)
break;
int MinId=-1,Min=1e9+1;
for(int i=0;i<NewId.size();i++)
{
Square Now=d[NewId[i]];
for(int j=1;j<=N;j++)
{
if(Del[j])
continue;
if(Bing(Now.xl,Now.xr,d[j].xl,d[j].xr)==false)
continue;
if(Now.yl<d[j].yr)
continue;
if(Min>Now.yl-d[j].yr-1)
{
Min=Now.yl-d[j].yr-1;
MinId=j;
}
}
}
for(int i=0;i<NewId.size();i++)
{
if(Min>=d[NewId[i]].yl)
{
Min=d[NewId[i]].yl;
MinId=-1;
}
}
if(MinId==-1||Min>=Sum)
{
if(Min>=Sum)
{
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl-=Sum;
d[NewId[i]].yr-=Sum;
}
Sum=0;
}
else
{
Sum-=Min;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl-=Min;
d[NewId[i]].yr-=Min;
}
}
break;
}
else
{
Sum-=Min;
Del[MinId]=true;
for(int i=0;i<NewId.size();i++)
{
d[NewId[i]].yl-=Min;
d[NewId[i]].yr-=Min;
}
NewId.push_back(MinId);
}
}
if(Sum>0)
{
printf("Command %d: MOVE - moved %d instead of %d\n",QId,dy-Sum,dy);
}
}
}
}
}
sort(d+1,d+N+1,cmp);
printf("%d window(s):\n",N);
for(int i=1;i<=N;i++)
{
printf("%d %d %d %d\n",d[i].yl,d[i].xl,Getw(d[i]),Geth(d[i]));
}
}
P7963 [NOIP2021] 棋局
#include<iostream>
#include <algorithm>
static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
template<typename item>
inline void read(register item &x)
{
bool flag=false;
x=0;register char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')
flag=true;
c=getchar();
}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(flag)
x=-x;
}
static char cc[10000];
template<typename item>
inline void print(register item x)
{
if(x==0)
{
cc[0]='0';
putchar(cc[0]);
return;
}
if(x<0)
{
cc[0]='-';
putchar(cc[0]);
x=-x;
}
register long long len=0;
while(x)cc[len++]=x%10+'0',x/=10;
while(len--)putchar(cc[len]);
}
const int MAXN=2e6+50;
void InOut(int op)
{
freopen("chess.in","r",stdin);
if(op)
freopen("chess.out","w",stdout);
}
int N,M,Q;
bool Can(int x,int y)
{
if(x<1||y<1||x>N||y>M)
return false;
return true;
}
int ALL;
int Edge[4][MAXN<<1];
int Ans[MAXN];
struct Node
{
int Color,Level,x,y,Id;
}Piece[MAXN];
bool CanEat(Node a,Node b)
{
if(a.Color!=b.Color&&a.Level>=b.Level)
return true;
return false;
}
bool cmp1(Node a,Node b)
{
if(a.Level==b.Level)
return a.Id<b.Id;
return a.Level<b.Level;
}
bool cmp2(Node a,Node b)
{
return a.Id<b.Id;
}
void LSHLevel()
{
std::sort(Piece+1,Piece+Q+1,cmp1);
for(int i=1;i<=Q;i++)
{
Piece[i].Level=i;
}
std::sort(Piece+1,Piece+Q+1,cmp2);
}
int HaveNode[MAXN];
int GetId(int op,int x,int y)
{
if(op==0)
return (x-1)*M+y;
else
return (y-1)*N+x;
}
int GetX(int Id)
{
return (Id-1)/M+1;
}
int GetY(int Id)
{
return (Id-1)%M+1;
}
int max(int a,int b)
{
return a>b?a:b;
}
struct SegmentTree
{
int Root[MAXN];
int ls[MAXN<<2],rs[MAXN<<2],Size[MAXN<<2];
int CntId;
void Init()
{
for(int i=1;i<=ALL;i++)
Root[i]=0;
for(int i=1;i<=CntId;i++)
{
ls[i]=rs[i]=Size[i]=0;
}
CntId=0;
}
int Merge(int u1,int u2,int l,int r)
{
if(u1&&u2)
{
if(u1==u2)
return u1;
}
if(!u1||!u2)
{
return u1+u2;
}
if(l==r)
{
Size[u1]=max(Size[u1],Size[u2]);
return u1;
}
int Mid=l+r>>1;
ls[u1]=Merge(ls[u1],ls[u2],l,Mid);
rs[u1]=Merge(rs[u1],rs[u2],Mid+1,r);
Size[u1]=Size[ls[u1]]+Size[rs[u1]];
return u1;
}
void Insert(int &u,int l,int r,int x)
{
if(u==0)
{
u=++CntId;
}
if(l==r)
{
Size[u]=1;
return;
}
int Mid=l+r>>1;
if(x<=Mid)
Insert(ls[u],l,Mid,x);
else
Insert(rs[u],Mid+1,r,x);
Size[u]=Size[ls[u]]+Size[rs[u]];
}
void Delete(int &u,int l,int r,int x)
{
if(u==0)
{
return;
}
if(l==r)
{
Size[u]=0;
return;
}
int Mid=l+r>>1;
if(x<=Mid)
Delete(ls[u],l,Mid,x);
else
Delete(rs[u],Mid+1,r,x);
Size[u]=Size[ls[u]]+Size[rs[u]];
}
int Query(int u,int l,int r,int x,int y)
{
if(!u)
return 0;
if(x<=l&&r<=y)
{
return Size[u];
}
int Mid=l+r>>1,Sum=0;
if(x<=Mid&&y>=l)
Sum+=Query(ls[u],l,Mid,x,y);
if(x<=r&&y>=Mid+1)
Sum+=Query(rs[u],Mid+1,r,x,y);
return Sum;
}
bool Query(int u,int l,int r,int x)
{
if(u==0)
{
return false;
}
if(l==r)
{
if(Size[u])
return true;
else
return false;
}
int Mid=l+r>>1;
if(x<=Mid)
return Query(ls[u],l,Mid,x);
else
return Query(rs[u],Mid+1,r,x);
}
}trId[2],trLevel[2];
void Insert1(int x,int y,int z)
{
trId[0].Insert(trId[0].Root[z],1,ALL,GetId(0,x,y));
trId[1].Insert(trId[1].Root[z],1,ALL,GetId(1,x,y));
}
void Insert2(int Nodeid,int z)
{
trLevel[Piece[Nodeid].Color].Insert(trLevel[0].Root[z],1,ALL,Piece[Nodeid].Level);
}
struct BingChaJi
{
int father[MAXN],Min[MAXN],Max[MAXN];
void Init()
{
for(int i=1;i<=ALL;i++)
{
father[i]=i;
Min[i]=1e9;Max[i]=0;
}
}
int getfather(int x)
{
if(x!=father[x])
father[x]=getfather(father[x]);
return father[x];
}
void Merge(int x,int y)
{
int fx=getfather(x),fy=getfather(y);
if(fx==fy)
return;
father[fy]=fx;
}
}Set[3];
void Init()
{
for(int i=1;i<=ALL;i++)
{
Edge[0][i]=Edge[1][i]=Edge[2][i]=Edge[3][i]=Ans[i]=HaveNode[i]=0;
}
trId[0].Init();
trId[1].Init();
trLevel[0].Init();
trLevel[1].Init();
Set[0].Init();
Set[1].Init();
Set[2].Init();
}
char opt[MAXN];
int dx[5]={0,-1,1,0,0},dy[5]={0,0,0,-1,1};
bool vis[MAXN];
int Mergedfs(int op,int x,int y,int fa)
{
if(op==4)
{
vis[GetId(0,x,y)]=true;
if(HaveNode[GetId(0,x,y+1)]==0&&Can(x,y+1)&&Edge[3][GetId(0,x,y)]==2)
{
Set[1].Merge(Set[1].getfather(GetId(0,x,fa)),Set[1].getfather(GetId(0,x,y+1)));
return Mergedfs(op,x,y+1,fa);
}
else
{
return y;
}
}
if(op==2)
{
vis[GetId(0,x,y)]=true;
if(HaveNode[GetId(0,x+1,y)]==0&&Can(x+1,y)&&Edge[1][GetId(0,x,y)]==2)
{
Set[2].Merge(Set[2].getfather(GetId(0,fa,y)),Set[2].getfather(GetId(0,x+1,y)));
return Mergedfs(op,x+1,y,fa);
}
else
{
return x;
}
}
}
void dfs3(int x,int y,int fx,int fy)
{
vis[GetId(0,x,y)]=true;
trId[0].Insert(trId[0].Root[GetId(0,fx,fy)],1,ALL,GetId(0,x,y));
trId[1].Insert(trId[1].Root[GetId(0,fx,fy)],1,ALL,GetId(1,x,y));
for(int i=0;i<4;i++)
{
if(Edge[i][GetId(0,x,y)]==3&&vis[GetId(0,x+dx[i+1],y+dy[i+1])]==false)
{
if(HaveNode[GetId(0,x+dx[i+1],y+dy[i+1])]==0)
{
Set[0].Merge(Set[0].getfather(GetId(0,fx,fy)),Set[0].getfather(GetId(0,x+dx[i+1],y+dy[i+1])));
dfs3(x+dx[i+1],y+dy[i+1],fx,fy);
}
else
{
int t=HaveNode[GetId(0,x+dx[i+1],y+dy[i+1])];
trLevel[Piece[t].Color].Insert(trLevel[Piece[t].Color].Root[GetId(0,fx,fy)],1,Q,Piece[t].Level);
}
}
}
}
void Read()
{
read(N);
read(M);
read(Q);
ALL=N*M;
Init();
for(int i=1;i<=N;i++)
{
for(int j=1;j<M;j++)
{
opt[j]=getchar();
while(opt[j]<'0'||opt[j]>'9')
opt[j]=getchar();
Edge[3][GetId(0,i,j)]=Edge[2][GetId(0,i,j+1)]=opt[j]-'0';
}
}
for(int i=1;i<N;i++)
{
for(int j=1;j<=M;j++)
{
opt[j]=getchar();
while(opt[j]<'0'||opt[j]>'9')
opt[j]=getchar();
Edge[0][GetId(0,i+1,j)]=Edge[1][GetId(0,i,j)]=opt[j]-'0';
}
}
for(int i=1;i<=Q;i++)
{
read(Piece[i].Color);
read(Piece[i].Level);
read(Piece[i].x);
read(Piece[i].y);
Piece[i].Id=i;
HaveNode[GetId(0,Piece[i].x,Piece[i].y)]=i;
}
}
int SolveEdge1(Node Now)
{
int ans=0;
int fx=Set[0].getfather(GetId(0,Now.x,Now.y));
for(int i=0;i<4;i++)
{
if(Edge[i][GetId(0,Now.x,Now.y)]==1)
{
if(HaveNode[GetId(0,Now.x+dx[i+1],Now.y+dy[i+1])]==0)
{
if(trId[0].Query(trId[0].Root[fx],1,ALL,GetId(0,Now.x+dx[i+1],Now.y+dy[i+1]))==false
{
ans++;
}
}
else
{
if(CanEat(Now,Piece[HaveNode[GetId(0,Now.x+dx[i+1],Now.y+dy[i+1])]]))
{
int NowColor=Piece[HaveNode[GetId(0,Now.x+dx[i+1],Now.y+dy[i+1])]].Color,NowLevel=Piece[HaveNode[GetId(0,Now.x+dx[i+1],Now.y+dy[i+1])]].Level;
if(trLevel[NowColor].Query(trLevel[NowColor].Root[fx],1,Q,NowLevel)==false)
{
ans++;
}
}
}
}
}
return ans;
}
#include <vector>
std::vector<int>Eatid;
int SolveEdge2(Node Now)
{
int ans=0;
int l1,r1,l2,r2;
l1=Set[1].Min[Set[1].getfather(GetId(0,Now.x,Now.y))];
r1=Set[1].Max[Set[1].getfather(GetId(0,Now.x,Now.y))];
l2=Set[2].Min[Set[2].getfather(GetId(0,Now.x,Now.y))];
r2=Set[2].Max[Set[2].getfather(GetId(0,Now.x,Now.y))];
int fx=Set[0].getfather(GetId(0,Now.x,Now.y));
ans+=r1-l1+1-trId[0].Query(trId[0].Root[fx],1,ALL,GetId(0,Now.x,l1),GetId(0,Now.x,r1));
ans+=r2-l2+1-trId[1].Query(trId[1].Root[fx],1,ALL,GetId(1,l2,Now.y),GetId(1,r2,Now.y));
Eatid.clear();
if(Edge[2][GetId(0,Now.x,l1)]==2)
Eatid.push_back(GetId(0,Now.x,l1-1));
if(Edge[3][GetId(0,Now.x,r1)]==2)
Eatid.push_back(GetId(0,Now.x,r1+1));
if(Edge[0][GetId(0,l2,Now.y)]==2)
Eatid.push_back(GetId(0,l2-1,Now.y));
if(Edge[1][GetId(0,r2,Now.y)]==2)
Eatid.push_back(GetId(0,r2+1,Now.y));
for(int i=0;i<Eatid.size();i++)
{
if(CanEat(Now,Piece[HaveNode[Eatid[i]]]))
{
int NowColor=Piece[HaveNode[Eatid[i]]].Color,NowLevel=Piece[HaveNode[Eatid[i]]].Level;
if(trLevel[NowColor].Query(trLevel[NowColor].Root[fx],1,Q,NowLevel)==false)
{
ans++;
}
}
}
return ans;
}
int SolveEdge3(Node Now)
{
int ans=0;
int fx=Set[0].getfather(GetId(0,Now.x,Now.y));
ans+=trId[0].Size[trId[0].Root[fx]]-trId[0].Query(trId[0].Root[fx],1,ALL,GetId(0,Now.x,Now.y));
ans+=trLevel[Now.Color^1].Query(trLevel[Now.Color^1].Root[fx],1,Q,1,Now.Level-1);
return ans;
}
std::vector<int>E2,E3;
int min(int x,int y)
{
return x<y?x:y;
}
void Del(Node Now)
{
HaveNode[GetId(0,Now.x,Now.y)]=0;
E3.clear();
for(int i=0;i<4;i++)
{
if(Edge[i][GetId(0,Now.x,Now.y)]==3)
{
E3.push_back(GetId(0,Now.x+dx[i+1],Now.y+dy[i+1]));
}
}
int ffx=Set[0].getfather(GetId(0,Now.x,Now.y));
trId[0].Insert(trId[0].Root[ffx],1,ALL,GetId(0,Now.x,Now.y));
trId[1].Insert(trId[1].Root[ffx],1,ALL,GetId(1,Now.x,Now.y));
for(int i=0;i<E3.size();i++)
{
int fx=Set[0].getfather(GetId(0,Now.x,Now.y)),fy=Set[0].getfather(E3[i]);
if(HaveNode[E3[i]])
{
int NowColor=Piece[HaveNode[E3[i]]].Color,NowLevel=Piece[HaveNode[E3[i]]].Level;
trLevel[NowColor].Insert(trLevel[NowColor].Root[fx],1,Q,NowLevel);
continue;
}
if(trId[0].Size[trId[0].Root[fy]])
trId[0].Root[fx]=trId[0].Merge(trId[0].Root[fx],trId[0].Root[fy],1,ALL);
if(trId[1].Size[trId[1].Root[fy]])
trId[1].Root[fx]=trId[1].Merge(trId[1].Root[fx],trId[1].Root[fy],1,ALL);
if(trLevel[0].Size[trLevel[0].Root[fy]])
trLevel[0].Root[fx]=trLevel[0].Merge(trLevel[0].Root[fx],trLevel[0].Root[fy],1,Q);
if(trLevel[1].Size[trLevel[1].Root[fy]])
trLevel[1].Root[fx]=trLevel[1].Merge(trLevel[1].Root[fx],trLevel[1].Root[fy],1,Q);
Set[0].Merge(fx,fy);
}
trLevel[Now.Color].Delete(trLevel[Now.Color].Root[ffx],1,Q,Now.Level);
if(Edge[0][GetId(0,Now.x,Now.y)]==Edge[1][GetId(0,Now.x,Now.y)]&&Edge[0][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x-1,Now.y)]==0&&HaveNode[GetId(0,Now.x+1,Now.y)]==0)
{
int fx=Set[2].getfather(GetId(0,Now.x-1,Now.y)),fy=Set[2].getfather(GetId(0,Now.x+1,Now.y));
Set[2].Max[fx]=Set[2].Max[fy];
Set[2].Merge(fx,fy);
Set[2].Merge(Set[2].getfather(GetId(0,Now.x-1,Now.y)),Set[2].getfather(GetId(0,Now.x,Now.y)));
}
else
{
if(Edge[0][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x-1,Now.y)]==0)
{
Set[2].Merge(Set[2].getfather(GetId(0,Now.x-1,Now.y)),Set[2].getfather(GetId(0,Now.x,Now.y)));
Set[2].Max[Set[2].getfather(GetId(0,Now.x-1,Now.y))]=Now.x;
}
else
{
if(Edge[1][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x+1,Now.y)]==0)
{
Set[2].Merge(Set[2].getfather(GetId(0,Now.x+1,Now.y)),Set[2].getfather(GetId(0,Now.x,Now.y)));
Set[2].Min[Set[2].getfather(GetId(0,Now.x+1,Now.y))]=Now.x;
}
else
{
Set[2].Min[GetId(0,Now.x,Now.y)]=Set[2].Max[GetId(0,Now.x,Now.y)]=Now.x;
}
}
}
if(Edge[2][GetId(0,Now.x,Now.y)]==Edge[3][GetId(0,Now.x,Now.y)]&&Edge[2][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x,Now.y-1)]==0&&HaveNode[GetId(0,Now.x,Now.y+1)]==0)
{
int fx=Set[1].getfather(GetId(0,Now.x,Now.y-1)),fy=Set[1].getfather(GetId(0,Now.x,Now.y+1));
Set[1].Max[fx]=Set[1].Max[fy];
Set[1].Merge(fx,fy);
Set[1].Merge(Set[1].getfather(GetId(0,Now.x,Now.y-1)),Set[1].getfather(GetId(0,Now.x,Now.y)));
}
else
{
if(Edge[2][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x,Now.y-1)]==0)
{
Set[1].Merge(Set[1].getfather(GetId(0,Now.x,Now.y-1)),Set[1].getfather(GetId(0,Now.x,Now.y)));
Set[1].Max[Set[1].getfather(GetId(0,Now.x,Now.y-1))]=Now.y;
}
else
{
if(Edge[3][GetId(0,Now.x,Now.y)]==2&&HaveNode[GetId(0,Now.x,Now.y+1)]==0)
{
Set[1].Merge(Set[1].getfather(GetId(0,Now.x,Now.y+1)),Set[1].getfather(GetId(0,Now.x,Now.y)));
Set[1].Min[Set[1].getfather(GetId(0,Now.x,Now.y+1))]=Now.y;
}
else
{
Set[1].Min[GetId(0,Now.x,Now.y)]=Set[1].Max[GetId(0,Now.x,Now.y)]=Now.y;
}
}
}
}
void Solve()
{
Read();
LSHLevel();
for(int i=1;i<=ALL;i++)
vis[i]=false;
for(int i=1;i<=N;i++)
{
for(int j=1;j<=M;j++)
{
if(HaveNode[GetId(0,i,j)]==0&&vis[GetId(0,i,j)]==0)
{
Set[1].Min[GetId(0,i,j)]=j;
Set[1].Max[GetId(0,i,j)]=Mergedfs(4,i,j,j);
}
}
}
for(int i=1;i<=ALL;i++)
vis[i]=false;
for(int i=1;i<=N;i++)
{
for(int j=1;j<=M;j++)
{
if(HaveNode[GetId(0,i,j)]==0&&vis[GetId(0,i,j)]==0)
{
Set[2].Min[GetId(0,i,j)]=i;
Set[2].Max[GetId(0,i,j)]=Mergedfs(2,i,j,i);
}
}
}
for(int i=1;i<=ALL;i++)
vis[i]=false;
for(int i=1;i<=N;i++)
{
for(int j=1;j<=M;j++)
{
if(vis[GetId(0,i,j)]==0&&HaveNode[GetId(0,i,j)]==0)
{
dfs3(i,j,i,j);
}
}
}
for(int i=Q;i>=1;i--)
{
Del(Piece[i]);
Ans[i]=SolveEdge1(Piece[i])+
SolveEdge2(Piece[i])+
SolveEdge3(Piece[i]);
}
for(int i=1;i<=Q;i++)
{
print(Ans[i]);
putchar('\n');
}
}
int main()
{
int T;
read(T);
while(T--)
{
Solve();
}
fwrite(obuf,p3-obuf,1,stdout);
}
未完待续。