T1 permut
可能逆序对这种东西天生血克我吧QAQ
结果还有打表找出规律来的???
结果最后还是个挺好想的DP????
靠,,,
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+10;
const int p=1e4;
int T;
int n,k;
int dp[MAXN][MAXN],g;
int Read(){
int i=0,f=1;
char c=getchar();
for(;(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
int main(){
T=Read();
dp[1][0]=1;
n=k=1000;
for(int i=2;i<=n;i++){
dp[i][0]=dp[i-1][0],g=dp[i-1][0];
for(int j=1;j<=min((i*(i-1)>>1),k);j++){
g=(g+dp[i-1][j])%p;
if(j-i>=0) g=(g-dp[i-1][j-i]+p)%p;
dp[i][j]=g%p;
}
}
while(T--){
n=Read();k=Read();
cout<<dp[n][k]<<'\n';
}
return 0;
}
T2 beautiful
嘻嘻嘻2k的数据肯定就往n^2上想了,因为之前做过类似思想的题,左右大小个数要相等,然后xjb维护一下就好了。
(下来有人给我说主席树可真是把我整懵了
#include<bits/stdc++.h>
using namespace std;
const int MAXN=2e3+10;
int n,q;
int a[MAXN];
int ans[MAXN];
int exist[MAXN][2];
struct Tree{
int l,r;
int maxx;
}tr[MAXN<<2];
int Read(){
int i=0,f=1;
char c=getchar();
for(;(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
#define lc (root<<1)
#define rc (root<<1|1)
void push_up(int root){tr[root].maxx=max(tr[lc].maxx,tr[rc].maxx);}
void build(int root,int l,int r){
tr[root].l=l,tr[root].r=r;
if(l==r){
tr[root].maxx=ans[l];
return ;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
push_up(root);
}
int query(int root,int l,int r,int L,int R){
if(l>R||r<L) return -0x3f3f3f3f;
if(L<=l&&r<=R) return tr[root].maxx;
int mid=l+r>>1;
if(R<=mid) return query(lc,l,mid,L,R);
else{
if(L>mid) return query(rc,mid+1,r,L,R);
else return max(query(lc,l,mid,L,mid),query(rc,mid+1,r,mid+1,R));
}
}
int main(){
n=Read();
for(int i=1;i<=n;++i) a[i]=Read();
for(int i=1;i<=n;++i){
memset(exist,-1,sizeof(exist));
exist[0][0]=0;
int dayu=0,xiaodeng=0;
for(int j=i-1;j;--j){
if(a[j]>a[i]) ++dayu;
else ++xiaodeng;
int flag=(dayu<xiaodeng);
exist[abs(dayu-xiaodeng)][flag]=i-j;
}
ans[i]=exist[0][0];
int dadeng=0,xiaoyu=0;
for(int j=i+1;j<=n;++j){
if(a[j]>=a[i]) ++dadeng;
else ++xiaoyu;
int flag=(dadeng<=xiaoyu),delta=abs(dadeng-xiaoyu);
if(exist[delta][flag^1]!=-1) ans[i]=max(ans[i],j-i+exist[delta][flag^1]);
}
}
for(int i=1;i<=n;++i) ++ans[i];
build(1,1,n);
q=Read();
while(q--){
int l=Read(),r=Read();
cout<<query(1,1,n,l,r)<<'\n';
}
}
T3 subset
一直不知道还有折半这种骚操作。。。。
思想就是分块,直接分成2^8个块标记前后缀,这样就能把复杂度降下来
#include<bits/stdc++.h>
using namespace std;
const int MAXN=260;
int n,s,tag,pre,suf,ans;
int kuai[MAXN][MAXN];
char cz[5];
int Read(){
int i=0,f=1;
char c=getchar();
for(;(c>'9'||c<'0')&&c!='-';c=getchar());
if(c=='-') f=-1,c=getchar();
for(;c>='0'&&c<='9';c=getchar()) i=(i<<3)+(i<<1)+c-'0';
return i*f;
}
int main(){
n=Read();
for(int i=1;i<=n;++i){
scanf("%s",cz),s=Read();
pre=s>>8,suf=s&255;
tag=(cz[0]=='d')?-1:1;
if(cz[0]!='c'){
for(int i=0;i<=255;++i) if((pre&i)==pre) kuai[i][suf]+=tag;
}
else{
ans=0;
for(int i=0;i<=255;++i) if((suf&i)==i) ans+=kuai[pre][i];
cout<<ans<<'\n';
}
}
}