The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)
Posted thusloop
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)相关的知识,希望对你有一定的参考价值。
F - Easy Fix
发现交换 l,r不会影响 1到l-1和r+1到 n
对l+1,r-1的影响只有正负一
对l和r再算一下
//#pragma GCC optimize(2)
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define yes cout<<"YES\\n"
#define no cout<<"NO\\n"
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf=8e18;
const int maxn=2e5+100;
int a[maxn],c[maxn],p[maxn],b[maxn],d[maxn],pre[maxn];
int lowbit(int x)
return x&(-x);
void update(int x,int val)
while(x<maxn)
c[x]+=val;
x+=lowbit(x);
int ask(int x)
int ans=0;
while(x>0)
ans+=c[x];
x-=lowbit(x);
return ans;
struct node
int l,r;
int sum;
int op[5];
t[maxn*32];
int cnt,root[maxn];
void update(int l,int r,int &x,int y,int num,vector<int>v)
x=++cnt;
t[x]=t[y];
t[x].sum++;
for(auto it:v) t[x].op[it]++;
//t[x].op[type]++;
if(l==r)return ;
int mid=(l+r)>>1;
if(num<=mid) update(l,mid,t[x].l,t[y].l,num,v);
else update(mid+1,r,t[x].r,t[y].r,num,v);
int query(int l,int r,int x,int y,int num,int type)//查询<= num [type]的个数
if(r<=num)return t[y].op[type]-t[x].op[type];
int mid=(l+r)>>1;
int ans=0;
if(num>=l) ans+=query(l,mid,t[x].l,t[y].l,num,type);
if(num>mid) ans+=query(mid+1,r,t[x].r,t[y].r,num,type);
return ans;
int query(int l,int r,int x,int y,int num)//查询<= num的个数
if(r<=num)return t[y].sum-t[x].sum;
int mid=(l+r)>>1;
int ans=0;
if(num>=l) ans+=query(l,mid,t[x].l,t[y].l,num);
if(num>mid) ans+=query(mid+1,r,t[x].r,t[y].r,num);
return ans;
signed main()
IOS
int n,q;
cin>>n;
for(int i=1; i<=n; i++)
cin>>p[i];
//cout<<"A:";
for(int i=1; i<=n; i++)
a[i]=ask(p[i]);
update(p[i],1);
//cout<<a[i]<<" ";
//cout<<"\\n";
//cout<<"B:";
for(int i=1; i<=n; i++) update(p[i],-1);
for(int i=n; i>=1; i--)
b[i]=ask(p[i]);
update(p[i],1);
d[i]=min(a[i],b[i]);
for(int i=1; i<=n; i++)
//cout<<b[i]<<" ";
pre[i]=pre[i-1]+d[i];
//cout<<"\\n";
for(int i=1; i<=n; i++)
vector<int>v;
if(a[i]<=b[i]) v.pb(1);
if(a[i]-1>b[i]) v.pb(2);
if(a[i]>=b[i]) v.pb(3);
if(a[i]<b[i]-1) v.pb(4);
update(1,(int)1e6,root[i],root[i-1],p[i],v);
cin>>q;
while(q--)
int l,r;
cin>>l>>r;
if(l>r) swap(l,r);
if(l==r)
cout<<pre[n]<<"\\n";
continue;
int ans=pre[n]-d[l]-d[r];
if(p[l]<p[r])
int s2=query(1,1e6,root[l],root[r-1],p[r],2)-query(1,1e6,root[l],root[r-1],p[l],2);
int s1=query(1,1e6,root[l],root[r-1],p[r],1)-query(1,1e6,root[l],root[r-1],p[l],1);
ans+=s2-s1;
else
int s4=query(1,1e6,root[l],root[r-1],p[l],4)-query(1,1e6,root[l],root[r-1],p[r],4);
int s3=query(1,1e6,root[l],root[r-1],p[l],3)-query(1,1e6,root[l],root[r-1],p[r],3);
ans+=s4-s3;
int low_l=query(1,1e6,root[l],root[r],p[l]);
int low_r=query(1,1e6,root[l-1],root[r-1],p[r]);
ans+=min(a[l]+low_l,b[l]-low_l);
ans+=min(a[r]-low_r,b[r]+low_r);
cout<<ans<<"\\n";
以上是关于The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)的主要内容,如果未能解决你的问题,请参考以下文章
The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)
The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)
The 19th Zhejiang Provincial Collegiate Programming Contest F - Easy Fix(主席树)
The 18th Zhejiang University Programming Contest
The 17th Zhejiang Provincial Contest B. Bin Packing Problem(线段树+map)
The 15th Zhejiang Provincial Collegiate Programming Contest(部分题解)