[考试总结]noip模拟7

为啥博客园 \(\LaTeX\) 老挂???!

\(\huge{\text{菜}}\)


刚开始写 \(T1\) 的时候,在看到后缀前缀之后,直接想到 \(AC\) 自动机,在画了半个 \(trie\) 树之后:

\(\huge{\text{这题也配用AC自动机???}}\)


然后秒写一个 \(hash\),之后一发过样例,以为稳了。。。

然后。。。

\(freopen\)

还好看到了。。。

不然就暴 \(\color{red}0\) \(\color{green}0\) \(\color{blue}0\)

似乎 \(kmp\) 也是可以做的,然而我不明白为什么看到这一题会先想到 \(kmp\) 而不是 \(hash\)。。。

\(code\)



#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
#define debug cout<<"debug"<<endl
//#define int long long 
FILE *file_eat; int scan_eat;
namespace xin_io
{
	#define freopen  file_eat = freopen
	#define scanf  scan_eat = scanf
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	inline int get()
	{
		int s = 0,f = 1;
		register char ch = gc();
		while(!isdigit(ch)) { if(ch == '-') f = -1;ch = gc();}
		while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io;
static const int maxn = 2e5+10; 
#define ull unsigned long long
namespace xin
{
	class xin_hash
	{
		public:
			ull h[maxn],p[maxn];
			int base;
			xin_hash(): base(13331){p[0] = 1;}
			inline void do_hash(char *s)
			{for(register int i=1;s[i];++i)h[i] = h[i-1] * base + (s[i] - 'a' + 1),p[i] = p[i-1] * base;}
			inline ull query(int l,int r)
			{return h[r] - h[l-1] * p[r - l + 1];}
	}ha,hb;
	int T,la,lb;
	char a[maxn],b[maxn];
	inline short main()
	{
	// #ifndef ONLINE_JUDGE
	// 	openfile();
	// #endif
		scanf("%d",&T);
		while(T--)
		{
			int ans = 0;
			scanf("%d%d",&la,&lb);
			scanf("%s",a+1);
//			cout<<a+1<<endl;
			char plus; cin>>plus; //cout<<"plus = "<<plus<<endl;
			for(register int i=1;i<=lb;++i)
				b[i] = a[i];
			b[++lb] = plus;
			ha.do_hash(a); hb.do_hash(b);
//			cout<<a[1]<<a[2]<<' '<<b[3]<<b[4]<<endl;
//			cout<<ha.query(1,1)<<' '<<hb.query(4,4)<<endl;
			int ms = min(la,lb);
//			for(register int i=1;b[i];++i) cout<<b[i];
			for(register int i=1;i<=ms;++i)
			{	
				register int j = lb - i + 1;
				if(ha.query(1,i) == hb.query(j,lb))
					ans = i;
			}
			printf("%d\n",ans);
		}
		return 0;
	}
}
signed main() {return xin::main();}

T2:

冲过 \(T1\) 之后,然后就开心地去冲 \(T2\)了,然后一眼看出 \(tarjan\) 割点板子。。。。

喜提 \(10pts\)

对于每一个割点,并不是都是有效割点,所以,我们只能标记 有效割点,其实只需要在考场代码上面加上两句话:

if(pd[y]) pd[x] = true;

还有判断上:

if((flag > 1 or x != 1) and pd[y]) cut[x] = true;

然后就是在 \(tarjan(i)\) 之前加上 pd[n] = true


就这???

  • 真 就这
    。。。。

所以你考场上为啥没想出来???

杠哥的话说,就是 \(\huge{\text{废*}}\)


别骂了,别骂了。。。。


所以 \(code\)



#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;
#define debug cout<<"debug"<<endl
//#define int long long 
FILE *file_eat; int scan_eat;
namespace xin_io
{
	#define freopen  file_eat = freopen
	#define scanf  scan_eat = scanf
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	inline int get()
	{
		int s = 0,f = 1;
		register char ch = gc();
		while(!isdigit(ch)) { if(ch == '-') f = -1;ch = gc();}
		while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io;
static const int maxn = 1e6+10;
#define ull unsigned long long
#include<cstring>
#define m(c,num) memset(c,num,sizeof c)
namespace xin
{
	class xin_edge{public:int next,ver;} edge[maxn<<2];
	int n,m;
	int num;
	int scc_num = 0;
	int dfn[maxn],low[maxn];
	int head[maxn],zhi;
	inline void add(int x,int y)
	{
		edge[++zhi].ver = y; 
		edge[zhi].next = head[x]; head[x] = zhi;
	}
	bool vis[maxn];
	bool cut[maxn];
	bool pd[maxn];
	inline void tarjan(int x)
	{
		dfn[x] = low[x] = ++num;
//		cout<<"x = "<<x<<" dfn[x] = "<<dfn[x]<<endl;
		int flag = 0,s = 0;
		for(register int i=head[x];i;i=edge[i].next)
		{
			register int y = edge[i].ver;
			if(!dfn[y])
			{
				tarjan(y);
				low[x] = min(low[x],low[y]);
				if(low[y] >= dfn[x])
				{
					flag++;		
					if((flag > 1 or x != 1) and pd[y]) cut[x] = 1;
				}
				if(pd[y]) pd[x] = 1;
			}
			else low[x] = min(low[x],dfn[y]);//,cout<<low[x]<<' '<<dfn[x]<<endl;
		}
	}
	int T;
	inline void clean()
	{
		num = zhi = 0;
		m(cut,0); m(low,0); m(dfn,0); m(pd,0);
		m(vis,0); m(edge,0); m(head,0); 
	}
	inline short main()
	{
	#ifndef ONLINE_JUDGE
		openfile();// outfile();
	#endif
		T = get();
		for(register int cse=1;cse<=T;++cse)
		{
			clean();
			n = get(); m = get();
			for(register int i=1;i<=m;++i)
			{
				register int x = get(),y = get();
				add(x,y); add(y,x);
			}
			pd[n] = 1;
			for(register int i=1;i<=n;++i)
				if(!dfn[i])
					tarjan(i);
			int cnt = 0;
			for(register int i=2;i<=n-1;++i)
				if(cut[i]) cnt++;//,cout<<"i = "<<i<<" cut[i] = "<<cut[i]<<endl;
			if(!cnt) {printf("0\n\n");continue;}
			printf("%d\n",cnt);
			for(register int i=2;i<=n-1;++i)
				if(cut[i]) printf("%d ",i); 
			printf("\n\n");
			clean();
//			cout<<(sizeof (edge) + sizeof(cut) + sizeof(dfn) + sizeof(low) + sizeof(vis) + sizeof(head)) / (1 << 20) <<"MB"<<endl;
		}	
//		for(register int i=1;i<=10;++i)
//			clean();
		return 0;
	}
}
signed main(){return xin::main();}

T3:

以为自己切掉 \(T2\) 之后,欢快地去打 \(T3\)。。。

然后。。。

逆序对???

思考一阵子之后,然后陷入了沉思。。。。

到了考试结束的时候也没想出一个所以然来。。。

可能是太想打正解了。。。

还不如莽一个 \(40pts\) 的暴力。

。。。。。


正解就是维护一个前缀和的前缀和,对,就这样。

然后二分起点。。。

之后就没啥了。。。

所以 \(code\):



#include<bits/stdc++.h>
using namespace std;
#define int long long 
#define debug cout<<"debug"<<endl
FILE *file_eat; int scan_eat;
namespace xin_io
{
	#define freopen  file_eat = freopen
	#define scanf  scan_eat = scanf
	#define gc() p1 == p2 and (p2 = (p1 = buf) + fread(buf,1,1<<20,stdin),p1 == p2) ? EOF : *p1++
	char buf[1<<20],*p1 = buf,*p2 = buf;
	inline void openfile() {freopen("t.txt","r",stdin);} inline void outfile() {freopen("o.txt","w",stdout);}
	inline int get()
	{
		int s = 0,f = 1;
		register char ch = gc();
		while(!isdigit(ch)) { if(ch == '-') f = -1;ch = gc();}
		while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = gc();}
		return s * f;
	}
}
using namespace xin_io;
static const int maxn = 2e6+10;
#define m(c,num) memset(c,num,sizeof c)
namespace xin
{
	int len,T;
	char s[maxn];
	int she[maxn],bhe[maxn],brhe[maxn];
	int ans;
//	inline int random(int x) {return (unsigned)rand() * rand() % x;}	
//	inline int getst(int l,int r){return random(r-2) + l;}
	int srhe[maxn],rhe[maxn];
	inline int query(int l,int v,int r) 
	{return she[v] - she[l-1] - bhe[l-1] * (rhe[v]-rhe[l-1]) + srhe[v+1] - srhe[r+1] - brhe[r+1] * (rhe[r] - rhe[v]);}
	inline bool pan(int num)
	{
		double every = (1.175 / ((1.0 * T))) * 1.0 * num;
//		cout<<every<<endl;
		register double tim = ((double)clock() / (double)(CLOCKS_PER_SEC));
		if(tim >= every) return false;
		return true;
	}
	bool vis[maxn];
	int num[maxn];
	inline short main()
	{
		#ifndef ONLINE_JUDGE
			openfile();
		#endif
		scanf("%lld",&T);
		for(register int cse=1;cse<=T;++cse)
		{
			register int cnt = 1;
		    scanf("%s",s+1); ans = 0x7f7f7f7f7f7f7f7f;
		    len = strlen(s+1);
		    for(register int i=1;i <= len;i++) s[i + len] = s[i];
		    for(register int i=1;i <= (len * 2);i++)
		    {
		        bhe[i] = bhe[i-1]; she[i] = she[i-1]; rhe[i] = rhe[i-1];
		        if(s[i] == 'R') bhe[i]++;
		        else rhe[i] ++,she[i] += bhe[i];
//				cout<<"bhe[i] = "<<bhe[i]<<" she[i] = "<<she[i]<<endl;
		    }
		    for(register int i=(len * 2);i;i--)
		    {
		        brhe[i] = brhe[i+1]; srhe[i] = srhe[i+1];
		        if(s[i] == 'R') brhe[i]++;
		        else srhe[i] += brhe[i];//,cout<<"srhe[i] = "<<srhe[i]<<endl;
		    }
			for(register int i=1;i<=len;++i)	
		    {
				//num[i]++;
//				cout<<"len = "<<len<<" i = "<<i<<endl;
//				if(vis[i]) continue;vis[i] = true;
		        while(cnt != len + i and query(i,cnt,i + len - 1) >= query(i,cnt + 1,i + len - 1)) cnt++;
		        ans = min(ans,query(i,cnt,i + len - 1));
		    }
		    cout<<ans<<endl;// m(vis,0);
//			for(register int i=1;i<=len;++i)
//				cout<<"i = "<<i<<" num[i] = "<<num[i]<<endl;
		}
		return 0;
	}
}
signed main() {return xin::main();}

posted @ 2021-06-11 21:32  NP2Z  阅读(31)  评论(1编辑  收藏  举报