写在前面
考试的时侯又naive了,以为自己能够搞出 70 p t s 70pts 70pts,然而时间不够了, 20 p t s 20pts 20pts滚粗。
Solution
首先拆环为链,否则在环上谁也搞不出来。
那么在链上上,原图中的每条通道可以看做一个区间,所以说我们可以考虑各种区间上的神奇操作。
注意到两条线相交实际上相当于区间有相交的地方。
那么令
b
i
t
1
[
i
]
[
j
]
bit1[i][j]
bit1[i][j]表示左端点小于等于
i
i
i,右端点小于等于
j
j
j的区间总数,
b
i
t
2
[
i
]
[
j
]
bit2[i][j]
bit2[i][j]表示左端点大于等于
i
i
i,右端点大于等于
j
j
j的区间总数。
然而这样做会发现计算会重复,所以说我们再定义
b
i
t
3
[
i
]
[
j
]
bit3[i][j]
bit3[i][j]表示左端点大于等于
i
i
i,右端点小于等于
j
j
j。这样的话我们就可以去掉重复计算的部分。
具体做法见代码。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
template <typename T>
void read(T &x){
x=0; int neg=1;
char c=getchar();
while(!isdigit(c)&&c!='-') c=getchar();
if(c=='-') neg=-1,c=getchar();
while(isdigit(c)) x=(x<<1)+(x<<3)+c-'0',c=getchar();
x*=neg;
}
int n,m,bit1[maxn][maxn],bit2[maxn][maxn],bit3[maxn][maxn];
inline int lowbit(int x){return x&-x;}
inline void update1(int x,int y,int v){//加入边(x,y)会影响到前面比他小的一些边,所以向前update
//维护a<x<b<y的情况
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
bit1[i][j]+=v;
}
inline void update2(int x,int y,int v){//加入边(x,y)会影响到后面比他钱的一些边,所以向后update
//维护x<a<y<b的情况
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
bit2[i][j]+=v;
}
inline void update3(int x,int y,int v){
//维护x<a<b<y的情况
for(int i=x;i;i-=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
bit3[i][j]+=v;
}
inline int query1(int x,int y){
int ret=0;
for(int i=x;i;i-=lowbit(i))
for(int j=y;j;j-=lowbit(j))
ret+=bit1[i][j];
return ret;
}
inline int query2(int x,int y){
int ret=0;
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j<=n;j+=lowbit(j))
ret+=bit2[i][j];
return ret;
}
inline int query3(int x,int y){
int ret=0;
for(int i=x;i<=n;i+=lowbit(i))
for(int j=y;j;j-=lowbit(j))
ret+=bit3[i][j];
return ret;
}
pair<int,int> qry[500005];
int main(){
read(n),read(m);
for(int i=1;i<=m;i++){
int op; read(op);
if(op==0){
int x,y; read(x),read(y);
if(x>y) swap(x,y);
int ansl=query1(x,y)-query3(1,x),ansr=query2(x,y)-query3(y,n);
printf("%d\n",ansl+ansr);
update1(x,y,1); update2(x,y,1); update3(x,y,1);
qry[i]=make_pair(x,y);
}
else{
int pos; read(pos);
int x=qry[pos].first,y=qry[pos].second;
update1(x,y,-1); update2(x,y,-1); update3(x,y,-1);
}
}
return 0;
}