J.Permutation Counting
题意:求n个数中不出现两个相差1的数的排列数。
这题其实只要考虑组合数学的思想就行了,判断最后一个数放哪里,如果前n-1个数已经没有出现相差1的一对数,那么n的位置有n-1个,如果前面出现一对相差1的数,那么n的位置有n-2个。感觉还是一个递推式吧,用一般的动态规划思想解决不了。
代码:
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<set> #include<queue> #include<cmath> #include<algorithm> #include<cstring> #include<map> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 1000005 #define N 1000000007 #define INF 0xfffffff #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(i,s,t) for(int i=s;i<=t;i++) #define ull unsigned long long #define ll long long using namespace std; int f[maxn]; void init() { f[1]=1,f[2]=1,f[3]=3; for(int i=4;i<=maxn;i++) f[i]=((ll)(i-1)*f[i-1]%N+(ll)(i-2)*f[i-2]%N)%N; } int main() { int t,tt=1; init(); scanf("%d",&t); while(t--) { int x; scanf("%d",&x); printf("Case %d: %d\n",tt++,f[x]); } return 0; }I An Average Game
这题题意是求一段区间去重之后的数的平均数。
其实只要每次把相同值的数的位置向后移动就行了,这样每次求和的时候肯定已经去重了。
代码:
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<set> #include<queue> #include<cmath> #include<algorithm> #include<cstring> #include<map> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 10005 #define INF 0xfffffff #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(i,s,t) for(int i=s;i<=t;i++) #define ull unsigned long long #define ll long long using namespace std; int a[maxn]; ll c[maxn],c2[maxn]; map<int,int> mp; int lowbit(int x) { return x&(-x); } void updata(int i,int x) { while(i<maxn) { c[i]+=x; i+=lowbit(i); } } ll sum(int i) { ll ret=0; while(i) { ret+=c[i]; i-=lowbit(i); } return ret; } void updata2(int i,int x) { while(i<maxn) { c2[i]+=x; i+=lowbit(i); } } ll sum2(int i) { ll ret=0; while(i) { ret+=c2[i]; i-=lowbit(i); } return ret; } void init() { mp.clear(); memset(c,0,sizeof(c)); memset(c2,0,sizeof(c2)); } struct node { int l,r,id; bool operator< (const node& x)const { return r<x.r; } }b[10*maxn]; double ans[10*maxn]; int main() { int t,tt=1; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } init(); int q; scanf("%d",&q); for(int i=1;i<=q;i++) { scanf("%d%d",&b[i].l,&b[i].r); b[i].id=i; } sort(b+1,b+1+q); int j=1; for(int i=1;i<=n;i++) { if(mp[a[i]]==0) { mp[a[i]]=i; updata(i,a[i]); updata2(i,1); } else { updata(mp[a[i]],-a[i]); updata2(mp[a[i]],-1); updata2(i,1); updata(i,a[i]); mp[a[i]]=i; } while(b[j].r==i) { ans[b[j].id]=1.0*(sum(b[j].r)-sum(b[j].l-1))/(sum2(b[j].r)-sum2(b[j].l-1)); j++; } } printf("Case %d:\n",tt++); for(int i=1;i<=q;i++) { printf("%.6lf\n",ans[i]); } } return 0; }