从i 到i+1 转移时候ans先倍增,再加上a[ i ] 加到双端队列两端时
对答案的贡献(既新出现的递减项)。然后有减法的时候取模一定要
先加mod再%mod,要不然WA到死 QAQ
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3929
递推
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
const int MAXN=1000;
const ll INF=1e9;
const ll mod=1e9+7;
ll a[100000+111];
ll sum[ 100000+111];
ll f[ 100000+111 ];
int n;
ll pre[ 100000+111];
int main()
{
//freopen("A-large.in","r",stdin);
//freopen("A-large.out","w",stdout);
pre[0]=1;
pre[1]=2;
for(int i=2;i<100000+11;i++){
pre[i]=(pre[i-1]*2)%mod;
}
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(sum,0,sizeof(sum));
for(int i=0;i<n;i++ ){
int tmp=0;
scanf("%d",&tmp);
a[i]=tmp;
}
f[0]=f[1]=0;
if(a[0]!=a[1])f[1]=1;
sum[ a[0] ]++;sum[ a[1] ]++;
for(int i=2;i<n;i++){
f[i]=(f[i-1]*2 +pre[i-1]-sum[ a[i] ] + mod )%mod;
sum[ a[i] ]= (sum[ a[i] ]+ pre[ i-1 ])%mod;
}
f[n-1]=(f[n-1]*2)%mod;
printf("%lld\n", f[n-1] );
}
return 0;
}
树状数组
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<queue>
#include<stack>
#include<list>
using namespace std;
typedef long long ll;
const int MAXN=1000;
const ll INF=1e9;
const ll mod=1e9+7;
ll a[100000+111];
ll bit[ 100000+111];
int n;
ll pre[ 100000+111];
ll sum(ll x){
ll ans=0;
while(x>0){
ans+=bit[x];
x-=x&(-x);
ans%=mod;
}
return ans;
}
void add( ll x,ll p ){
while(x<=100000+12){
bit[x]+=p;
bit[x]%=mod;
x+=x&(-x);
}
}
int main()
{
//freopen("A-large.in","r",stdin);
//freopen("A-large.out","w",stdout);
pre[0]=1;
pre[1]=2;
for(int i=2;i<100000+11;i++){
pre[i]=(pre[i-1]*2)%mod;
}
int t;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(bit,0,sizeof(bit));
for(int i=0;i<n;i++ ){
int tmp=0;
scanf("%d",&tmp);
a[i]=tmp;
}
ll ans=0;
if(a[0]!=a[1])ans=1;
add(a[0],1);
add( a[1],1 );
for(int i=2;i<n;i++){
ll t1=sum( a[i]-1 );
ll t2=sum( a[i] );
ll t3=sum( 100000+12 );
ans=(ans*2)%mod;
//printf("i==%d ans==%I64d\n",i,ans);
//printf("t1==%I64d t2==%I64d t3==%I64d\n",t1,t2,t3);
ans=(ans+t1+t3-t2 +mod )%mod;
add( a[i],pre[i-1] );
}
ans=(ans*2)%mod;
printf("%lld\n", ans );
}
return 0;
}