QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#153672 | #6304. Rectangle | chen_zexing | WA | 52ms | 24928kb | C++17 | 11.9kb | 2023-08-30 18:27:18 | 2023-08-30 18:27:18 |
Judging History
answer
#pragma GCC optimize("Ofast,unroll-loops")
#include <bits/stdc++.h>
using namespace std;
long long mod=998244353;
int b[200005];
long long qpow(long long a,long long b){
long long ans=1;
while(b){
if(b&1) ans=ans*a%mod;
b>>=1;
a=a*a%mod;
}
return ans;
}
struct seg_tree{
struct nod{
int mn,mx,id;
long long sum,w;
}tree[800005];
multiset <int> s[200005];
int n;
void init(int node,int l,int r){
tree[node].mn=tree[node].mx=1e9;
tree[node].id=node;
if(l==r){
tree[node].sum=1LL*(b[l+1]-b[l])*tree[node].mx%mod;
tree[node].w=(b[l+1]-b[l]);
return;
}
int mid=(l+r)>>1;
init(node*2,l,mid),init(node*2+1,mid+1,r);
tree[node].sum=(tree[node*2].sum+tree[node*2+1].sum)%mod;
tree[node].w=(tree[node*2].w+tree[node*2+1].w)%mod;
}
nod merge(nod a,nod b){
//cout<<"#"<<a.sum<<" "<<b.sum<<endl;
if(a.mn==a.mx){
nod ans;
if(a.mn<b.mn) ans.mn=a.mn,ans.mx=b.mx,ans.sum=(a.sum+b.sum)%mod,ans.id=-1,ans.w=(a.w+b.w)%mod;
else ans.mn=b.mn,ans.mx=b.mx,ans.sum=(b.sum+1LL*b.mn*a.w)%mod,ans.id=-1,ans.w=(a.w+b.w)%mod;
return ans;
}
else{
if(tree[a.id*2+1].mn<b.mn){
nod temp=merge(tree[a.id*2+1],b);
//cout<<a.sum<<" "<<b.sum<<" "<<temp.sum<<endl;
return nod{a.mn,b.mx,-1,(a.sum-tree[a.id*2+1].sum+temp.sum)%mod,(a.w+b.w)%mod};
}
else{
b.sum=(b.sum+tree[a.id*2+1].w*b.mn)%mod,b.w=(b.w+tree[a.id*2+1].w)%mod;
return merge(tree[a.id*2],b);
}
}
}
void update(int node,int l,int r,int pos,int v){
if(l==r){
tree[node].mn=tree[node].mx=v;
tree[node].sum=tree[node].w*v%mod;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) update(node*2,l,mid,pos,v);
else update(node*2+1,mid+1,r,pos,v);
tree[node]=merge(tree[node*2],tree[node*2+1]);
tree[node].id=node;
//cout<<pos<<" "<<v<<endl;
//cout<<l<<" "<<r<<" "<<tree[node].sum<<endl;
}
nod query(int node,int l,int r,int L,int lb,nod pre){
if(L>r) return nod{0,0,0,0,0};
if(l>=L){
if(tree[node].mx<lb) return pre;
if(tree[node].mn>=lb) return merge(tree[node],pre);
int mid=(l+r)>>1;
if(tree[node*2+1].mn>=lb) return query(node*2,l,mid,L,lb,merge(tree[node*2+1],pre));
else return query(node*2+1,mid+1,r,L,lb,pre);
}
int mid=(l+r)>>1;
if(L<=mid) return query(node*2,l,mid,L,lb,merge(tree[node*2+1],pre));
else return query(node*2+1,mid+1,r,L,lb,pre);
}
int query_sg(int node,int l,int r,int pos){
if(l==r) return tree[node].mn;
int mid=(l+r)>>1;
if(pos<=mid) return min(tree[node*2+1].mn,query_sg(node*2,l,mid,pos));
else return query_sg(node*2+1,mid+1,r,pos);
}
void init(int len){
n=len;
for(int i=1;i<=n;i++) s[i].clear();
init(1,1,n);
}
void insert(int pos,int x){
if(!pos) return;
s[pos].insert(x);
update(1,1,n,pos,(*s[pos].begin()));
}
void del(int pos,int x){
if(!pos) return;
s[pos].erase(s[pos].find(x));
if(s[pos].size()) update(1,1,n,pos,*s[pos].begin());
else update(1,1,n,pos,1e9);
}
long long query(int l,int r,int bd){
if(l>r) return 0;
//cout<<l<<" "<<r<<" "<<bd<<endl;
auto t1=query(1,1,n,l,bd,nod{int(1e9),int(1e9),0,0,0}),t2=query(1,1,n,r+1,bd,nod{int(1e9),int(1e9),0,0,0});
//cout<<t1.sum<<" "<<t2.sum<<" "<<t1.w-t2.w<<endl;
long long ans=((t1.sum-t2.sum-(t1.w-t2.w)*(bd-1))%mod+mod)%mod;
return ((t1.sum-t2.sum-(t1.w-t2.w)*(bd-1))%mod+mod)%mod;
}
}Tr;
int x[100005],y[100005],xx[100005],yy[100005];
int yv[200005];
map <int,vector<pair<int,int>>> mp[2];
long long dp[300005][4],predp[300005][4];
int xv[100005],xxv[100005],pre[200005],c[300005];
long long C(int n,int m){
if(n<m) return 0;
long long ans=1,fac=1;
for(int i=n;i>n-m;i--) ans*=i,ans%=mod;
for(int i=m;i;i--) fac=fac*i%mod;
//cout<<n<<" "<<m<<" "<<ans*qpow(fac,mod-2)%mod<<endl;
return ans*qpow(fac,mod-2)%mod;
}
int main() {
int T = 1, kase = 0;
cin >> T;
while (T--) {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d%d%d%d",&x[i],&y[i],&xx[i],&yy[i]);
if(T==994){
cout<<n<<endl;
for(int i=1;i<=n;i++) cout<<x[i]<<" "<<y[i]<<" "<<xx[i]<<" "<<yy[i]<<endl;
}
long long ans=0;
multiset <int> lp;
multiset <int,greater<int>> rp;
lp.clear(),rp.clear();
int cnt,ycnt;
cnt=0,ycnt=0;
mp[0].clear(),mp[1].clear();
for(int i=1;i<=n;i++){
b[++cnt]=x[i],b[++cnt]=xx[i],yv[++ycnt]=y[i],yv[++ycnt]=yy[i];
mp[1][y[i]].push_back({x[i],xx[i]}),mp[0][yy[i]].push_back({x[i],xx[i]});
}
b[++cnt]=1,b[++cnt]=1e9+1;
sort(b+1,b+cnt+1);
cnt=unique(b+1,b+cnt+1)-b-1;
yv[++ycnt]=1,yv[++ycnt]=1e9;
sort(yv+1,yv+ycnt+1);
ycnt=unique(yv+1,yv+ycnt+1)-yv-1;
Tr.init(cnt-1);
for(int i=1;i<=n;i++){
lp.insert(xx[i]),rp.insert(x[i]);
Tr.insert(lower_bound(b+1,b+cnt+1,x[i])-b-1,xx[i]);
}
for(int i=1;i<=ycnt;i++){
//cout<<yv[i]<<" "<<yv[i+1]<<endl;
for(auto t:mp[1][yv[i]]){
//cout<<"----"<<t.first<<" "<<t.second<<endl;
lp.erase(lp.find(t.second)),rp.erase(rp.find(t.first));
Tr.del(lower_bound(b+1,b+cnt+1,t.first)-b-1,t.second);
}
int lb=lp.size()?(*lp.begin()):1e9,rb=rp.size()?(*rp.begin()):1;
ans+=Tr.query(1,lower_bound(b+1,b+cnt+1,lb)-b-1,rb),ans%=mod;
ans+=max(0,Tr.query_sg(1,1,cnt-1,lower_bound(b+1,b+cnt+1,lb)-b)-rb+1),ans%=mod;
if(lb>=rb) ans-=1LL*(lb-rb+2)*(lb-rb+1)/2,ans%=mod;
if(ans<0) ans+=mod;
//cout<<ans<<endl;
if(i!=ycnt){
for(auto t:mp[0][yv[i]]){
lp.insert(t.second),rp.insert(t.first);
Tr.insert(lower_bound(b+1,b+cnt+1,t.first)-b-1,t.second);
}
lb=lp.size()?(*lp.begin()):1e9,rb=rp.size()?(*rp.begin()):1;
ans+=Tr.query(1,lower_bound(b+1,b+cnt+1,lb)-b-1,rb)*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
ans+=1LL*max(0,Tr.query_sg(1,1,cnt-1,lower_bound(b+1,b+cnt+1,lb)-b)-rb+1)*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
if(lb>=rb) ans-=1LL*(lb-rb+2)*(lb-rb+1)/2%mod*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
if(ans<0) ans+=mod;
}
//cout<<ans<<endl;
}
int cc=0;
for(int i=1;i<=n;i++) c[++cc]=x[i],c[++cc]=xx[i]+1,c[++cc]=xx[i];
c[++cc]=1,c[++cc]=1e9+1;
sort(c+1,c+cc+1),cc=unique(c+1,c+cc+1)-c-1;
for(int i=0;i<=cc;i++) pre[i]=-1;
for(int i=1;i<=n;i++){
xv[i]=lower_bound(c+1,c+cc+1,x[i])-c;
xxv[i]=lower_bound(c+1,c+cc+1,xx[i])-c;
//cout<<xv[i]<<" "<<xxv[i]<<endl;
pre[xxv[i]]=max(pre[xxv[i]],xv[i]);
}
for(int i=1;i<=cc;i++){
pre[i]=max(pre[i],pre[i-1]);
//cout<<"#"<<i<<" "<<pre[i]<<endl;
}
dp[0][0]=predp[0][0]=1;
for(int i=1;i<cc;i++){
for(int j=1;j<=3;j++) {
dp[i][j]=0;
for (int k = 0; k < j; k++)
dp[i][j] += (predp[i - 1][k] - (pre[i-1] == -1 ? 0 : predp[pre[i-1]-1][k])) * C(c[i + 1] - c[i], j - k) %
mod, dp[i][j] %= mod;
//cout<<"dp[i][j] "<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
for(int j=0;j<=3;j++) predp[i][j]=(predp[i-1][j]+dp[i][j])%mod;
if(pre[cc]<=i) ans=(ans+dp[i][3])%mod;
}
//cout<<ans<<endl;
for(int i=1;i<=n;i++) swap(x[i],y[i]),swap(xx[i],yy[i]);
lp.clear(),rp.clear();
cnt=0,ycnt=0;
mp[0].clear(),mp[1].clear();
for(int i=1;i<=n;i++){
b[++cnt]=x[i],b[++cnt]=xx[i],yv[++ycnt]=y[i],yv[++ycnt]=yy[i];
mp[1][y[i]].push_back({x[i],xx[i]}),mp[0][yy[i]].push_back({x[i],xx[i]});
}
b[++cnt]=1,b[++cnt]=1e9+1;
sort(b+1,b+cnt+1);
cnt=unique(b+1,b+cnt+1)-b-1;
yv[++ycnt]=1,yv[++ycnt]=1e9;
sort(yv+1,yv+ycnt+1);
ycnt=unique(yv+1,yv+ycnt+1)-yv-1;
Tr.init(cnt-1);
for(int i=1;i<=n;i++){
lp.insert(xx[i]),rp.insert(x[i]);
Tr.insert(lower_bound(b+1,b+cnt+1,x[i])-b-1,xx[i]);
}
for(int i=1;i<=ycnt;i++){
//cout<<yv[i]<<" "<<yv[i+1]<<endl;
for(auto t:mp[1][yv[i]]){
//cout<<"----"<<t.first<<" "<<t.second<<endl;
lp.erase(lp.find(t.second)),rp.erase(rp.find(t.first));
Tr.del(lower_bound(b+1,b+cnt+1,t.first)-b-1,t.second);
}
int lb=lp.size()?(*lp.begin()):1e9,rb=rp.size()?(*rp.begin()):1;
ans+=Tr.query(1,lower_bound(b+1,b+cnt+1,lb)-b-1,rb),ans%=mod;
ans+=max(0,Tr.query_sg(1,1,cnt-1,lower_bound(b+1,b+cnt+1,lb)-b)-rb+1),ans%=mod;
if(lb>=rb) ans-=1LL*(lb-rb+2)*(lb-rb+1)/2,ans%=mod;
if(ans<0) ans+=mod;
//cout<<ans<<endl;
if(i!=ycnt){
for(auto t:mp[0][yv[i]]){
lp.insert(t.second),rp.insert(t.first);
Tr.insert(lower_bound(b+1,b+cnt+1,t.first)-b-1,t.second);
}
lb=lp.size()?(*lp.begin()):1e9,rb=rp.size()?(*rp.begin()):1;
ans+=Tr.query(1,lower_bound(b+1,b+cnt+1,lb)-b-1,rb)*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
ans+=1LL*max(0,Tr.query_sg(1,1,cnt-1,lower_bound(b+1,b+cnt+1,lb)-b)-rb+1)*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
if(lb>=rb) ans-=1LL*(lb-rb+2)*(lb-rb+1)/2%mod*(yv[i+1]-yv[i]-1)%mod,ans%=mod;
if(ans<0) ans+=mod;
}
//cout<<ans<<endl;
}
cc=0;
for(int i=1;i<=n;i++) c[++cc]=x[i],c[++cc]=xx[i]+1,c[++cc]=xx[i];
c[++cc]=1,c[++cc]=1e9+1;
sort(c+1,c+cc+1),cc=unique(c+1,c+cc+1)-c-1;
for(int i=0;i<=cc;i++) pre[i]=-1;
for(int i=1;i<=n;i++){
xv[i]=lower_bound(c+1,c+cc+1,x[i])-c;
xxv[i]=lower_bound(c+1,c+cc+1,xx[i])-c;
//cout<<xv[i]<<" "<<xxv[i]<<endl;
pre[xxv[i]]=max(pre[xxv[i]],xv[i]);
}
for(int i=1;i<=cc;i++){
pre[i]=max(pre[i],pre[i-1]);
//cout<<"#"<<i<<" "<<pre[i]<<endl;
}
dp[0][0]=predp[0][0]=1;
for(int i=1;i<cc;i++){
for(int j=1;j<=3;j++) {
dp[i][j]=0;
for (int k = 0; k < j; k++)
dp[i][j] += (predp[i - 1][k] - (pre[i-1] == -1 ? 0 : predp[pre[i-1]-1][k])) * C(c[i + 1] - c[i], j - k) %
mod, dp[i][j] %= mod;
//cout<<"dp[i][j] "<<i<<" "<<j<<" "<<dp[i][j]<<endl;
}
for(int j=0;j<=3;j++) predp[i][j]=(predp[i-1][j]+dp[i][j])%mod;
if(pre[cc]<=i) ans=(ans+dp[i][3])%mod;
}
//cout<<ans<<endl;
for(int i=1;i<=n;i++) swap(x[i],y[i]),swap(xx[i],yy[i]);
printf("%lld\n",(ans%mod+mod)%mod);
}
return 0;
}
/*
3
1
1 1 1000000000 1000000000
3
1 1 2 2
3 3 4 4
5 5 6 6
5
581574116 47617804 999010750 826131769
223840663 366320907 613364068 926991396
267630832 51913575 488301124 223957497
217461197 492085159 999485867 913732845
28144453 603781668 912516656 993160442
*/
/*
1
3
1 1 2 2
3 3 4 4
5 5 6 6
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 24328kb
input:
3 1 1 1 1000000000 1000000000 3 1 1 2 2 3 3 4 4 5 5 6 6 5 581574116 47617804 999010750 826131769 223840663 366320907 613364068 926991396 267630832 51913575 488301124 223957497 217461197 492085159 999485867 913732845 28144453 603781668 912516656 993160442
output:
230616300 64 977066618
result:
ok 3 number(s): "230616300 64 977066618"
Test #2:
score: -100
Wrong Answer
time: 52ms
memory: 24928kb
input:
1000 10 5 7 6 10 4 3 6 9 1 6 3 7 1 1 7 10 1 2 7 7 5 2 8 3 2 1 5 7 1 1 10 6 1 7 2 8 4 7 5 9 10 6 6 8 10 4 4 9 9 2 4 6 5 5 3 10 10 1 3 4 4 2 2 3 6 7 5 8 6 2 7 8 8 5 7 10 10 2 4 7 8 10 3 6 6 10 1 2 7 4 7 5 10 9 4 5 8 9 2 7 5 9 2 2 9 7 3 3 8 4 1 1 8 6 5 4 10 6 3 9 7 10 10 3 1 8 9 1 3 8 10 4 1 7 4 2 4 5 ...
output:
28090346 21067815 91293528 63203269 14045217 10 3 2 9 8 9 3 10 5 1 4 2 5 4 5 6 6 2 1 4 6 3 1 5 2 4 3 8 6 1 3 8 5 2 1 10 10 6 2 10 9 28090337 50913763 56180656 10533942 83 28090372 101827338 514657075 38624242 12289571 42135595 7022614 7022661 7022622 31601641 21067817 35112979 7022628 7022682 175564...
result:
wrong answer 6th numbers differ - expected: '24579047', found: '10'