結果
| 問題 |
No.2160 みたりのDominator
|
| コンテスト | |
| ユーザー |
华恋~韵
|
| 提出日時 | 2024-04-14 11:17:24 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 59 ms / 2,000 ms |
| コード長 | 3,530 bytes |
| コンパイル時間 | 1,848 ms |
| コンパイル使用メモリ | 175,004 KB |
| 実行使用メモリ | 16,896 KB |
| 最終ジャッジ日時 | 2024-10-03 08:10:50 |
| 合計ジャッジ時間 | 7,253 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 93 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0;
char c;
while(c=getchar())if(c>='0'&&c<='9')break;
while(c>='0'&&c<='9'){
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x;
}
const int N=8000006,M=2700005;
int n1,n2,n3,m,cf[3][N],min1[N][2],max1[N][2],num,suf[2][N],tag[M<<2],S,T,N1,N2,N3,ID=3;
long long tr[M<<2];
inline void add(int op,int l,int r){
++cf[op][l],--cf[op][r+1];
}
struct line{
int x,y1,y2,v;
}L[N<<1];
inline bool cmp(line x,line y){
return x.x<y.x;
}
inline void pushdown(int k,int l,int r){
if(tag[k]){
int mid=(l+r)>>1;
tag[k<<1]+=tag[k],tag[k<<1|1]+=tag[k];
tr[k<<1]+=1ll*tag[k]*(cf[2][mid+n2]-cf[2][l-1+n2]),tr[k<<1|1]+=1ll*tag[k]*(cf[2][r+n2]-cf[2][mid+n2]);
tag[k]=0;
}
}
inline void update(int k,int l,int r,int x,int y){
if(l>=x&&r<=y){
++tag[k],tr[k]+=cf[2][r+n2]-cf[2][l-1+n2];
return;
}
pushdown(k,l,r);
int mid=(l+r)>>1;
if(x<=mid)update(k<<1,l,mid,x,y);
if(y>=mid+1)update(k<<1|1,mid+1,r,x,y);
tr[k]=tr[k<<1]+tr[k<<1|1];
}
inline long long query(int k,int l,int r,int x,int y){
if(l>=x&&r<=y)return tr[k];
pushdown(k,l,r);
long long ans=0;
int mid=(l+r)>>1;
if(x<=mid)ans+=query(k<<1,l,mid,x,y);
if(y>=mid+1)ans+=query(k<<1|1,mid+1,r,x,y);
return ans;
}
inline int calc(int x){
if(x>n3)return x;
if(ID==3)return x;
if(ID==1){
if(x<=N1)return N3+N2+x;
if(x<=N1+N2)return x-N1+N3;
return x-N1-N2;
}
if(x<=N1)return x;
if(x<=N1+N2)return x+N3;
return x-N2;
}
int main(){
n1=read(),n2=read(),n3=read(),m=read();
N1=n1,N2=n2,N3=n3;
if(n1<n2&&n1<n3)ID=1,swap(n1,n3);
else if(n2<n3)ID=2,swap(n2,n3);
n2+=n1;
n3+=n2;
S=n3+1;
T=S+1;
int x,y;
for(int i=1;i<=n1;++i)min1[i][0]=min1[i][1]=T;
for(int i=n1+1;i<=n2;++i)min1[i][0]=T;
while(m--){
x=calc(read()),y=calc(read());
if(x>y)swap(x,y);
if(y==T){
if(x==S){
cout<<0;
return 0;
}
if(x<=n1)add(0,x+1,n1+1);
else if(x<=n2)add(1,x+1,n2+1);
else add(2,x+1,n3+1);
}
else if(y==S){
if(x<=n1)add(0,1,x);
else if(x<=n2)add(1,n1+1,x);
else add(2,n2+1,x);
}
else{
if(y<=n1)add(0,x+1,y);
else if(y<=n2){
if(x<=n1){
min1[x][0]=min(min1[x][0],y);
max1[x][0]=max(max1[x][0],y);
}
else add(1,x+1,y);
}
else{
if(x<=n1){
min1[x][1]=min(min1[x][1],y);
max1[x][1]=max(max1[x][1],y);
}
else if(x<=n2){
min1[x][0]=min(min1[x][0],y);
max1[x][0]=max(max1[x][0],y);
}
else add(2,x+1,y);
}
}
}
for(int i=0;i<=2;++i){
for(int j=1;j<=n3+1;++j)cf[i][j]+=cf[i][j-1];
}
suf[0][n1+1]=n2+1,suf[1][n1+1]=n3+1;
for(int i=n1;i;--i)suf[0][i]=min(suf[0][i+1],min1[i][0]),suf[1][i]=min(suf[1][i+1],min1[i][1]);
int pre0=n1+1,pre1=n2+1;
for(int i=1;i<=n1+1;++i){
if(i!=1)pre0=max(pre0,max1[i-1][0]+1),pre1=max(pre1,max1[i-1][1]+1);
if(!cf[0][i]&&pre0<=suf[0][i]&&pre1<=suf[1][i]){
L[++num]={suf[0][i],pre1,suf[1][i],1};
if(pre0!=n1+1)L[++num]={pre0-1,pre1,suf[1][i],-1};
}
}
sort(L+1,L+num+1,cmp);
pre0=n2+1,suf[0][n2+1]=n3+1;
for(int i=n2;i>n1;--i)suf[0][i]=min(suf[0][i+1],min1[i][0]);
for(int i=n2+1;i<=n3+1;++i)cf[2][i]=cf[2][i-1]+(cf[2][i]==0);
int now=0;
long long ans=0;
for(int i=n1+1;i<=n2+1;++i){
if(i!=n1+1)pre0=max(pre0,max1[i-1][0]+1);
if(!cf[1][i]&&pre0<=suf[0][i])update(1,1,n3-n2+1,pre0-n2,suf[0][i]-n2);
while(now+1<=num&&L[now+1].x==i){
++now;
ans+=1ll*L[now].v*query(1,1,n3-n2+1,L[now].y1-n2,L[now].y2-n2);
}
}
cout<<ans;
}
华恋~韵