USACO19JAN Gold题解

噩梦的回忆。。

上周日在机房打的模拟赛,结果十分惨烈,就最后一题yy出了正解结果玄学的只拿了80

考试结果:0+0+80=80

订正时对着T3打了2hours结果还是90

订正结果:100+100+90=290

我太弱了QAQ

T1 Luogu P5196 [USACO19JAN]Cow Poetry

题目链接

思路:dp+神奇的数学推导

快速幂一开始还写锅了,受到了ftq大佬的嘲笑

code

#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7,MAXN=5000+10;
int f[5010][MAXN],s[MAXN],c[MAXN],g[MAXN],num[35],n,m,k;
long long ans,re=1;
long long pow(int b, int p) {
    if (p == 0) {
        return 1;
    }
    long long x = b;
    long long ans = 1;
    while (p > 0) {
        if (p % 2 == 1) {
            ans = ans * x % MOD;
        }
        x = x * x % MOD;
        p = p >> 1;
    }
    return ans % MOD;
}
void debug()
{
	for(int i=1;i<=5;++i){
		cout<<f[k][i]<<" ";
	}
	cout<<endl;
	for(int i=0;i<=5;++i){
		cout<<num[i]<<" ";
	}
	cout<<endl;
}
signed main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
	cin>>n>>m>>k;
	for(int i=1;i<=n;++i){
		cin>>s[i]>>c[i];
	}
	g[0]=1;
	for(int i=1;i<=k;i++){
		for(int j=1;j<=n;j++){
			if(i-s[j]>=0){
				(f[i][c[j]]+=g[i-s[j]])%=MOD;
				(g[i]+=g[i-s[j]])%=MOD;
			}
		}
	}
	for(int i=1;i<=m;++i){
		char ch;
		cin>>ch;
		num[ch-'A']++;
	}
//	debug();
	for(int i=0;i<26;++i){
		if(num[i]){
			ans=0;
			for(int j=1;j<=n;++j){
				if(f[k][j]){
					(ans+=pow(f[k][j],num[i]))%=MOD;
//					cout<<ans<<endl;
					
				}
			}
			(re*=ans)%=MOD;
		}
	}
	cout<<re<<endl;
	return 0;
}

T2 Luogu P5200 [USACO19JAN]Sleepy Cow Sorting

题目链接

思路:神奇的推导+树状数组

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
inline int lowbit(int x){return x&(-x);}
int ans[MAXN],num[MAXN],tree[MAXN],n,sum,k;
void add(int x)
{
	for(int i=x;i<=n;i+=lowbit(i)){
		tree[i]++;
	}
}
int query(int x)
{
	int re=0;
	for(int i=x;i;i-=lowbit(i)){
		re+=tree[i];
	}
	return re;
}
int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;++i){
		cin>>num[i];
	}
	sum=n,k=0;
	while(num[n-k]>num[n-k-1]){
		add(num[n-k]);
		sum--,k++;
	}
	add(num[n-k]);
	sum--;
	for(int i=1;i<=sum;++i){
		add(num[i]);
		ans[i]=sum-i+query(num[i]-1);
	}
	cout<<sum<<endl;
	for(int i=1;i<=sum;++i){
		cout<<ans[i]<<" ";
	}
	return 0;
}

T3 Luogu P5201 [USACO19JAN]Shortcut

思路:dij+最短路树

code

#include<bits/stdc++.h>
#define int long long 
#define ll long long 
using namespace std;
const int MAXN=1e5+10,INF=0x3f3f3f3f;
inline int read()
{
	int s=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		s=s*10+ch-'0';
		ch=getchar();
	}
	return s*f;
}

struct NODE {
    int first,second;
    bool operator<(NODE b) const { return (b.first==first)?b.second<second:b.first < first; }
};
int cnt,Cnt,m,n,T;
int head[MAXN],Head[MAXN],from[MAXN],siz[MAXN],v[MAXN];
ll dist[MAXN],ans=0;
priority_queue <NODE > q;
bool vis[MAXN],vi[MAXN];

void debug()
{
	puts("head	Head	from	siz	dist");
	for(int i=1;i<=n;++i){
		cout<<head[i]<<"	"<<Head[i]<<"	"<<from[i]<<"	"<<siz[i]<<"	"<<dist[i]<<endl;
	}
}

struct node{
	int to,next,l;	
}edge[MAXN];
void addedge(int x,int y,int l)
{
	edge[++cnt].to=y;
	edge[cnt].l=l;
	edge[cnt].next=head[x];
	head[x]=cnt;
}

struct Node{
	int to,next;
}Edge[MAXN];
void Addedge(int x,int y)
{
	Edge[++Cnt].to=y;
	Edge[Cnt].next=Head[x];
	Head[x]=Cnt;
}

void dij()
{
	memset(dist,INF,sizeof(dist));
	dist[1]=0;
	NODE a;
	a.first=0,a.second=1;
	q.push(a);
	while(!q.empty()){
		NODE now=q.top();q.pop();
		int x=now.second;
//		if(vi[x])continue;
//		vi[x]=1;
//		cout<<x<<"while\n";
		for(int i=head[x];i;i=edge[i].next){
//			cout<<i<<"i\n";
			int y=edge[i].to;
//			cout<<y<<" y\n";
			if(dist[x]+edge[i].l<dist[y]){			
//				cout<<y<<"y\n";
				NODE aa;
				aa.second=y,aa.first=dist[y];
				dist[y]=dist[x]+edge[i].l;
				from[y]=x;
//				cout<<"to"<<y<<endl;
				q.push(aa);
			}
		}
	}
}

void build()
{
	for(int i=1;i<=n;++i){
		Addedge(i,from[i]);
		Addedge(from[i],i);
	}
}

int dfs(int x,int fa)
{
	vis[x]=1;
	siz[x]+=v[x];
	for(int i=Head[x];i;i=Edge[i].next){
		int y=Edge[i].to;
		if(!vis[y]&&y!=fa){
			siz[x]+=dfs(y,x);
		}
	}
	return siz[x];
}

signed main()
{
//	freopen("test08.in","r",stdin);
//	freopen("1.out","w",stdout);
	cin>>n>>m>>T;
	for(int i=1;i<=n;++i){
		v[i]=read();
	}
	for(int i=1;i<=m;++i){
		int x=read(),y=read(),t=read();
		addedge(x,y,t);
		addedge(y,x,t);
	}
	dij();
	build();
	dfs(1,0);
//	debug();
	for(int i=1;i<=n;++i){
		ans=max(ans,siz[i]*(dist[i]-T));
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2019-09-29 09:27  zhu_chen  阅读(140)  评论(0编辑  收藏  举报