QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#153666 | #6304. Rectangle | chen_zexing | WA | 43ms | 24916kb | C++17 | 11.7kb | 2023-08-30 17:59:57 | 2023-08-30 17:59:58 |
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]);
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
*/
详细
Test #1:
score: 100
Accepted
time: 5ms
memory: 24844kb
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: 43ms
memory: 24916kb
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 28090337 50913763 56180656 10533942 83 28090372 101827338 514657075 38624242 12289571 42135595 7022614 7022661 7022622 31601641 21067817 35112979 7022628 7022682 17556485 42135554 59692019 28090452 15800844 73737099 47402422 31601703 49158091 28090434 108...
result:
wrong answer 6th numbers differ - expected: '24579047', found: '28090337'