2018.08.31测试

D2

T1

             就是一道比较好想的dp题啦,一开始是想开三维询问最大最小值,但后来发现预处理个ST表O(1)查询就可以省下一维啦,题解的做法和我的有点点不一样呐,题解上市倒着枚举的然后就可以线性递推维护最大最小值了,题解时间复杂度为(nm),我的做法的时间复杂度为(nlogn+nm),在m较大时可以忽略为O(nm),可能会慢一点点但很好想也好些。然后考试的时候一不小心把min(mini[l][k],mini[r-(1<<k)+1][k])写成了min(mini[l][k],maxi[r-(1<<k)+1][k])orz,然后全班这道题就我没A(吧?)QAQ

             

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#define inf 0x7ffffffffff
#define maxn 20005
#define maxm  1005
using namespace std;

int n,m,k;
int mini[maxn][21],maxi[maxn][21];
long long dp[maxn];

int read()
{
	int xx=0,kk=1;char ch=' ';
	while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
	while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
	return kk*xx;
}

inline int qmax(int l,int r)
{
	int k=log(r-l+1);
	return max(maxi[l][k],maxi[r-(1<<k)+1][k]);
}

inline int qmin(int l,int r)
{
	int k=log(r-l+1);
	return min(mini[l][k],mini[r-(1<<k)+1][k]);
}

int main()
{
    freopen("toy.in","r",stdin);
    freopen("toy.out","w",stdout);
	n=read(),m=read(),k=read();
	for(int i=1;i<=n;++i) 
	    maxi[i][0]=mini[i][0]=read();
    for(int j=1;j<=log(n)+1;++j)
    for(int i=1;i+(1<<j)-1<=n;++i)
    {
    	maxi[i][j]=max(maxi[i][j-1],maxi[i+(1<<(j-1))][j-1]);
		mini[i][j]=min(mini[i][j-1],mini[i+(1<<(j-1))][j-1]);
	}
	for(int i=1;i<=n;++i) dp[i]=inf;
	for(int i=1;i<=n;++i)
	for(int l=1;l<=m&&l+i-1<=n;++l)
	{
		int j=i+l-1;
		dp[j]=min(dp[j],dp[i-1]+1ll*l*(qmax(i,j)-qmin(i,j))+1ll*k);
	}
	printf("%lld",dp[n]);    
	return 0;
}

T2

              考试的时候想出了正解!!(我可真是个小天才)

              但我偷懒吧用dep[u]和dep[v]的关系来决定该边有没有做贡献,然后后面可能修改到的某条边与dep[u],dep[v]完全没有关系!这样判断就会导致某些边使得cnt[v]更新多次,然后gg。所以以后还是不要偷懒啦!!

               然后之后改判边修改过没的时候,一个地方要把我改死啦!!就是那该死的位运算的优先级,(r-1)<<1+1运算出来的结果不是((r-1)<<1)+1而是(r-1)<<(1+1)(呕)。果然以后位运算能打括号的地方还是都尽量要打上哒QwQ

              

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <queue>
#define inf 0x7fffffff
#define maxn 100010
#define maxm  200010
using namespace std;

bool vis[maxn<<1];
int n,m,q,u,v,num,ans,r;
int fir[maxn],dot[maxm][2],cnt[maxn],dep[maxn];
queue<int> que;

struct qwq
{
	int to,nxt;
}e[maxm<<1];

int read()
{
	int xx=0,kk=1;char ch=' ';
	while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;}
	while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();}
	return kk*xx;
}

void addedge(int u,int v)
{
	e[num].to=v;
	e[num].nxt=fir[u];
	fir[u]=num++;
}

void bfs()
{
	que.push(1);dep[1]=1;
	while(!que.empty())
	{
		int u=que.front();que.pop();
		for(int i=fir[u];i!=-1;i=e[i].nxt)
		{
			
			int v=e[i].to;
			if(dep[v]==dep[u]+1) cnt[v]++;
			if(!dep[v]) 
			    dep[v]=dep[u]+1,cnt[v]=1,que.push(v);
		}
	}
}

void modify(int u,int edge)
{
	if(!cnt[u]||vis[edge]||vis[edge^1]) return;
	vis[edge]=vis[edge^1]=true;
	if(--cnt[u]==0) ans++;
	else return;
	for(int i=fir[u];i!=-1;i=e[i].nxt)
	{
		int v=e[i].to;
		if(dep[u]<dep[v])
		    modify(v,i);
	}
}

int main()
{
    freopen("train.in","r",stdin);
    freopen("train.out","w",stdout);
	n=read(),m=read(),q=read();
	memset(fir,-1,sizeof(fir));
	for(int i=1;i<=m;++i)
	{
		u=read(),v=read();
		addedge(u,v);addedge(v,u);
		dot[i][0]=u,dot[i][1]=v;
	}
	
	bfs();cnt[1]=inf;
	while(q--)
	{
		r=read();
		int d0=dot[r][0];
		int d1=dot[r][1];
		if(dep[d0]==dep[d1]||vis[(r-1)<<1]||vis[((r-1)<<1)+1])
		{
			printf("%d\n",ans);
			continue;
		}
		if(dep[d0]>dep[d1]) swap(d0,d1);
		modify(d1,(r-1)<<1);
		printf("%d\n",ans);
	}
	return 0;
}

T3

            辣鸡数据结构!还没改完!

TO BE CONTINUED...

猜你喜欢

转载自blog.csdn.net/qq_40942982/article/details/82290821