社区讨论
求卡常
题目总版参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mhjst20w
- 此快照首次捕获于
- 2025/11/04 07:55 4 个月前
- 此快照最后确认于
- 2025/11/04 07:55 4 个月前
Time limit exceeded on test 2
主要应该是线段树常数太大了,加之n<=1e6
CPP#pragma GCC optimize(2,3,"Ofast","inline")
#include <bits/stdc++.h>
//#define int long long
#define ll long long
#define double long double
#define pii pair<int,int>
#define fi first
#define se second
#define mp(x,y) make_pair(x,y)
#define pb(x) push_back(x)
#define sz(s) ((int)s.size())
#define lowbit(x) (x&-x)
#define endl "\n"
using namespace std;
void inline solve(int C);
signed main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
srand(time(0));
int T=1,C=0;
//cin >> C;
cin >> T;
while(T--) solve(C);
return 0;
}
const int N=3e6+10;
int n,p,q,bst[N],dp[N],mx[N*4],tg[N*4];
ll s[N*4],ans;
vector<int> lsh,v;
pii a[N];
void inline add(int x,int k){
while(x<=sz(lsh)){
bst[x]=max(bst[x],k);
x+=lowbit(x);
}
}
int inline ask(int x){
int res=0;
while(x){
res=max(res,bst[x]);
x^=lowbit(x);
}
return res;
}
bool cmp(pii x,pii y){
if(x.fi!=y.fi) return x.fi<y.fi;
return x.se>y.se;
}
void inline pushdown(int idx,int l,int r){
if(tg[idx]==-1) return;
int mid=(l+r)/2;
mx[idx*2]=mx[idx*2+1]=tg[idx];
s[idx*2]=1ll*(lsh[mid-1]-lsh[l-1]+1)*tg[idx];
s[idx*2+1]=1ll*(lsh[r-1]-lsh[mid-1])*tg[idx];
tg[idx*2]=tg[idx*2+1]=tg[idx];
tg[idx]=-1;
}
void inline pushup(int idx){
mx[idx]=max(mx[idx*2],mx[idx*2+1]);
s[idx]=s[idx*2]+s[idx*2+1];
}
void inline modify(int fl,int fr,int val,int l=1,int r=sz(lsh),int idx=1){
if(fl==l && fr==r){
s[idx]=1ll*(lsh[r-1]-lsh[l-1]+1)*val;
mx[idx]=val;
tg[idx]=val;
return;
}
int mid=(l+r)/2;
pushdown(idx,l,r);
if(fr<=mid) modify(fl,fr,val,l,mid,idx*2);
else if(fl>mid) modify(fl,fr,val,mid+1,r,idx*2+1);
else modify(fl,mid,val,l,mid,idx*2),modify(mid+1,fr,val,mid+1,r,idx*2+1);
pushup(idx);
}
int inline query(int val,int l=1,int r=sz(lsh),int idx=1){
if(mx[idx]<val) return r;
if(l==r) return l;
int mid=(l+r)/2;
pushdown(idx,l,r);
if(mx[idx*2]<=val) return query(val,l,mid,idx*2);
return query(val,mid+1,r,idx*2+1);
}
ll inline ASK(int fl,int fr,int l=1,int r=sz(lsh),int idx=1){
if(fl==l && fr==r) return s[idx];
int mid=(l+r)/2;
pushdown(idx,l,r);
if(fr<=mid) return ASK(fl,fr,l,mid,idx*2);
else if(fl>mid) return ASK(fl,fr,mid+1,r,idx*2+1);
return ASK(fl,mid,l,mid,idx*2)+ASK(mid+1,fr,mid+1,r,idx*2+1);
}
void inline solve(int C){
lsh.clear();
cin >> n >> p >> q;
for(int i=1;i<=n;i++){
cin >> a[i].fi >> a[i].se;
v.pb(a[i].fi-1),v.pb(a[i].fi),v.pb(a[i].fi+1);
lsh.pb(max(a[i].se-1,0)),lsh.pb(a[i].se),lsh.pb(a[i].se+1);
}
v.pb(0),lsh.pb(0),v.pb(p),v.pb(p-1),v.pb(p+1),lsh.pb(q),lsh.pb(q-1),lsh.pb(q+1);
sort(lsh.begin(),lsh.end());
lsh.resize(unique(lsh.begin(),lsh.end())-lsh.begin());
sort(v.begin(),v.end());
v.resize(unique(v.begin(),v.end())-v.begin());
sort(a+1,a+1+n,cmp);
for(int i=1;i<=sz(lsh);i++) bst[i]=0;
for(int i=1;i<=4*sz(lsh);i++) s[i]=mx[i]=0,tg[i]=-1;
for(int i=1;i<=n;i++){
int x=lower_bound(lsh.begin(),lsh.end(),a[i].se)-lsh.begin()+1;
dp[i]=ask(x)+1;
add(x,1);
}
ans=1ll*(p+1)*p/2*(q+1)+1ll*(q+1)*q/2*(p+1);
int L=lower_bound(lsh.begin(),lsh.end(),0)-lsh.begin()+1;
int R=lower_bound(lsh.begin(),lsh.end(),q)-lsh.begin()+1;
for(int i=0,j=1;i<sz(v)-1;i++){
while(j<=n && a[j].fi+1==v[i]){
int x=lower_bound(lsh.begin(),lsh.end(),a[j].se+1)-lsh.begin()+1;
int y=query(dp[j]);
if(x<=y) modify(x,y,dp[j]);
j++;
}
if(v[i]<=p && v[i]>=0) ans-=1ll*(v[i+1]-v[i])*ASK(L,R);
}
cout << ans << endl;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...