20150808训练题+解题报告

题目资源

原题:

链接:http://pan.baidu.com/s/1sjurjZ3 密码:fph5

没什么意思的题解【想看的话】:

链接:http://pan.baidu.com/s/1mg3oNkW 密码:hrgw

第三题题解【来源 Codeforces】:

链接:http://pan.baidu.com/s/1i33uSIx 密码:nz0c

线段树讲稿【附带T2题解】:

链接:http://pan.baidu.com/s/10RwyM 密码:i7iq

这次的训练我没有参加,但代码还是都写了的,表示仍然没有发现是NOIP题

【T1】mikado

#include <bits/stdc++.h>

using namespace std;

const int N =  1000010;

int n,m;
struct Node{
	int v;
	Node *nxt;
}pool[N],*tail=pool,*g[N];
int ind[N],q[N],l,r;

char buf[20<<20],*cur=buf;

inline int rd(){
	int t=0;
	for(;!isdigit(*cur);cur++);
	for(;isdigit(*cur);t=t*10+*cur++-'0');
	return t;
}
int main()
{
	freopen("mikado.in","r",stdin);
	freopen("mikado.out","w",stdout);
	fread(buf,1,sizeof(buf),stdin);
	//scanf("%d%d",&n,&m);
	n=rd();m=rd();
	for(int i=1;i<=m;i++){
		int u,v;
		u=rd();v=rd();
		tail->v=v;tail->nxt=g[u];g[u]=tail++;
		ind[v]++;
	}
	l=1,r=0;
	for(int i=1;i<=n;i++) if(!ind[i]) q[++r]=i;
	while(l<=r){
		int u=q[l];l++;
		for(Node *p=g[u];p;p=p->nxt) if(!--ind[p->v])
			q[++r]=p->v;
	}
	printf("%d\n",r);
	return 0;
}


【T2】grimoire

#include <bits/stdc++.h>

using namespace std;

const int N = 300010;
const int MP = 1000000000;

typedef long long LL;

struct Node{
	int size;
	LL sum;
	Node *lc,*rc;
}pool[N*35*2],*tail=pool,*rt[N];

int n,m;
char op[30];

inline void mdf(Node *&rt,int l,int r,int x,int dt){
	if(!rt) rt=tail++;
	rt->size+=dt;rt->sum+=dt*x;
	if(l==r) return;
	int mid=l+r>>1;
	if(x<=mid) mdf(rt->lc,l,mid,x,dt);
	else mdf(rt->rc,mid+1,r,x,dt);
}
inline int qrySize(Node *rt,int l,int r,int x){
	if(!rt) return 0;
	if(l==r) return rt->size;
	int mid=l+r>>1;
	return x>mid ? qrySize(rt->rc,mid+1,r,x) : (rt->rc?rt->rc->size:0)+qrySize(rt->lc,l,mid,x);
}
inline LL qrySum(Node *rt,int l,int r,int x){
	if(!rt) return 0;
	if(l==r) return 1ll*l*x;
	int mid=l+r>>1,rs=rt->rc?rt->rc->size:0;
	return x<=rs ? qrySum(rt->rc,mid+1,r,x) : (rt->rc?rt->rc->sum:0)+qrySum(rt->lc,l,mid,x-rs);
}
inline int qryKth(Node *rt,int l,int r,int k){
	if(!rt) return 0;
	if(l==r) return l;
	int mid=l+r>>1,rs=rt->rc?rt->rc->size:0;
	return k<=rs ? qryKth(rt->rc,mid+1,r,k) : qryKth(rt->lc,l,mid,k-rs);
}

char buf[20<<20],*cur=buf;

inline int rd(){
	int t=0;
	for(;!isdigit(*cur);cur++);
	for(;isdigit(*cur);t=t*10+*cur++-'0');
	return t;
}

inline void rs(char *ct){
	for(;!isalpha(*cur);cur++);
	for(;isalpha(*cur);*(ct++)=*(cur++));
}
int main()
{
	freopen("grimoire.in","r",stdin);
	freopen("grimoire.out","w",stdout);
	fread(buf,1,sizeof(buf),stdin);
//	scanf("%d%d",&n,&m);
	n=rd();m=rd();
	for(int i=1;i<=m;i++){
		int t,p;
		rs(op);t=rd();p=rd();
		//scanf("%s%d%d",op,&t,&p);
		if(op[0]=='B'){
			mdf(rt[t],1,MP,p,1);
			if(qrySize(rt[t],1,MP,p)<=t){
				int kt=qryKth(rt[t],1,MP,t+1);
				if(kt) mdf(rt[0],1,MP,kt,-1);
				mdf(rt[0],1,MP,p,1);
			}
		}
		else{
			if(qrySize(rt[t],1,MP,p)<=t){
				int kt=qryKth(rt[t],1,MP,t+1);
				mdf(rt[0],1,MP,p,-1);
				if(kt) mdf(rt[0],1,MP,kt,1);
			}
			mdf(rt[t],1,MP,p,-1);
		}
		printf("%lld\n",qrySum(rt[0],1,MP,n));
	}
	return 0;
}

【T3】magic

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const LL MOD = 1000000007;

int n,k;
LL C[15][15];
LL f[210][210][10];
int flag[10][10]={
	{1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 },
	{1 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 },
	{1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 },
	{1 ,2 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 },
	{1 ,2 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 },
	{1 ,1 ,1 ,0 ,0 ,1 ,0 ,0 ,0 ,0 },
	{1 ,0 ,2 ,0 ,0 ,0 ,1 ,0 ,0 ,0 },
	{1 ,3 ,0 ,2 ,1 ,0 ,0 ,1 ,0 ,0 },
	{1 ,2 ,1 ,1 ,0 ,2 ,0 ,0 ,1 ,0 },
	{1 ,4 ,0 ,4 ,2 ,0 ,0 ,4 ,0 ,1 }
},dt1[10]={12,9,6,6,6,3,0,3,0,0}
 ,dt2[10]={4 ,2,1,1,0,0,0,0,0,0};

int main()
{
	freopen("magic.in","r",stdin);
	freopen("magic.out","w",stdout);
	scanf("%d%d",&n,&k);
	C[0][0]=1;
	for(int i=1;i<15;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++)
			C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
	}
	
	f[0][0][0]=1;
	f[0][1][1]=4;f[0][1][2]=4;
	f[0][2][3]=4;f[0][2][4]=2;f[0][2][5]=8;f[0][2][6]=2;
	f[0][3][7]=4;f[0][3][8]=4;
	f[0][4][9]=1;
	
	for(int i=0;i<n;i++)
		for(int j=0;j<10;j++)
			for(int p=0;p<=k;p++) if(f[i][p][j]){
				for(int q=0;q<10;q++) if(flag[j][q]){
					int left1=dt1[q],left2=dt2[q];
					for(int r=0;p+r<=k && r<=left2;r++)
						for(int t=0;p+r+t<=k && t<=left1-2*r;t++)
							(f[i+1][p+r+t][q]+=(f[i][p][j]*C[left2][r])%MOD*C[left1-2*r][t]*flag[j][q])%=MOD;
				}
			}

	LL ans=0;
	for(int j=0;j<10;j++) (ans+=f[n][k][j])%=MOD;
	for(int i=1;i<=k;i++) (ans*=i)%=MOD;
	printf("%lld\n",ans);
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值