题解 english
骗分骗到70pts不会动了。。。亿小会后再来补坑吧。
首先1~4\(O(n^2)\)暴力过掉20pts,对于opt=1的点,单调栈求出每个点的延伸范围,
式子很好推,得40pts,
对于\(1>=a_i>=0\)的点opt=2显然ans=0,直接输出得10pts
代码就不放了,改完再放
update in 7.13
终于过了...调了半天发现自己没扔初值,后来疯狂Wa是数组开小了...
对于ans2建立可持久化TRIE树,对于每个l r看左右区间哪个小就对它查找,注意取膜即可。
Code
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
namespace EMT{
#define pf printf
#define int long long
#define F(i,a,b) for(register int i=a;i<=b;i++)
#define D(i,a,b) for(register int i=a;i>=b;i--)
typedef long long ll;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
inline int min(int a,int b){return a<b?a:b;}inline int max(int a,int b){return a>b?a:b;}
inline void pi(ll x){pf("%lld ",x);}inline void pn(){pf("\n");}
inline void file(){freopen("in.in","r",stdin);freopen("my.out","w",stdout);}
const int mod=1e9+7,N=1e5+100;
int n,opt,a[N],l[N],r[N],tot,top,pre[N][22],son[N<<5][2],root[N],sum[N<<5],bin[22];ll maxn,ans1,ans2;
struct node{int v,od;}stack[N],pp;
inline void build(int &p,int dep){
p=++tot;
if(dep==20)return;
build(son[p][0],dep+1);
build(son[p][1],dep+1);
}
inline void insert(int x,int &y,int v,int dep){
y=++tot;
sum[y]=sum[x]+1;
if(dep<0)return;
int t=(v>>dep)&1;
son[y][t^1]=son[x][t^1];
insert(son[x][t],son[y][t],v,dep-1);
}
inline int query(int x,int y,int v,int pos,int val,int dep){
if(dep<0)return 0;
//pi(pos);pi(dep);pn();
int t=(pos>>dep)&1;
if(val+bin[dep]>v)return sum[son[y][t^1]]-sum[son[x][t^1]]+query(son[x][t],son[y][t],v,pos,val,dep-1);
return query(son[x][t^1],son[y][t^1],v,pos,val+bin[dep],dep-1);
}
inline void check(int x,int dep){
if(dep<-1)return;
pf("dep: ");pi(dep);
pf("son0: "),pi(sum[son[x][0]]),pn();
if(sum[son[x][0]])check(son[x][0],dep-1);
pf("dep: ");pi(dep);
pf("son1: "),pi(sum[son[x][1]]),pn();
if(sum[son[x][1]])check(son[x][1],dep-1);
}
inline short main(){
file();
n=read(),opt=read();
F(i,1,n)a[i]=read();bin[0]=1;
F(i,1,20)bin[i]=bin[i-1]<<1;
F(i,1,n){
l[i]=r[i]=i;pp.v=a[i];pp.od=i;
while(top&&stack[top].v<a[i])r[stack[top].od]=i-1,l[i]=l[stack[top].od],--top;
stack[++top]=pp;
}while(top)r[stack[top].od]=n,top--;
F(i,1,n)F(j,0,20)pre[i][j]=((a[i]&(1<<j))?1:0)+pre[i-1][j];
F(i,1,n)if(l[i]!=r[i])F(j,0,19)(ans1+=(ll)((ll)(pre[i][j]-pre[l[i]-1][j])*((r[i]-i+1)-(pre[r[i]][j]-pre[i-1][j]))+(ll)(pre[r[i]][j]-pre[i-1][j])*((i-l[i]+1)-(pre[i][j]-pre[l[i]-1][j])))%mod*a[i]%mod*(1<<j)%mod)%=mod;
if(opt==1){pi(ans1);return 0;}
if(opt==3)pi(ans1),pn();
build(root[0],0);
F(i,1,n)insert(root[i-1],root[i],a[i],20);
F(i,1,n)if(l[i]!=r[i]){if(i-l[i]<=r[i]-i)F(j,l[i],i)(ans2+=(ll)a[i]*query(root[i-1],root[r[i]],a[i],a[j],0,20)%mod)%=mod;else F(j,i,r[i])(ans2+=(ll)a[i]*query(root[l[i]-1],root[i],a[i],a[j],0,20)%mod)%=mod;}
pi(ans2);
return 0;
}
}
signed main(){return EMT::main();}
Everything that kills me makes me feel alive.