ICPC 2019-2020 North-Western Russia Regional Contest AEHJM

A:簽到模擬即可

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;

int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}



int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int a,b,n;
  	cin>>a>>b>>n;
  	int l=0,L=0,r=a,R=b;
  	int tp=1;
  	int c=b-a;
  	tp+=(n-b+c-1)/c*2;
  	
	cout<<tp<<endl;
	return 0;
}

E:問距離相同的點,直接把m個點加到隊列裏跑bfs。

由於是距離,所以不能走回頭路,即加個vs數組,訪問過的點不再加入隊列。

一個點v滿足條件必須要:這m個點在同一時刻到達v。//(即在BFS的同一層到達)

我們開一個nm數組,表示同一時刻,(m個標記點種)有多少點到達i。

只有滿足dep[y]=dep[x]+1才能往下更新(即在同一時刻到達y)然後轉移nm即可。

只要出現nm[y]==m的情況,就說明找到了目標點v輸出即可。

找不到說明沒有滿足條件的點。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;

int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
struct node{
	int x,dep;
};
queue<node>q;
int vs[M],n,m;
int dep[M];
int nm[M];//點i有nm[i]個點在同一時刻訪問 
bool flag;
void bfs()
{
	while(q.size())
	{
		node tp=q.front();q.pop();
		int x=tp.x;
		for(int i=head[tp.x];i;i=ee[i].nxt)
		{
			int y=ee[i].to;
			//cout<<x<<"  "<<y<<" "<<nm[x]<<" "<<dep[x]<<"  "<<dep[y]<<endl;
			
			if(!dep[y]||dep[y]==dep[x]+1)//y點未訪問過或剛好到達x的點再到y,與到y點的時刻相同 
			{
				nm[y]+=nm[x];
				if(nm[y]==m){
					flag=true;
					cout<<"YES"<<endl;
					cout<<y<<endl;
					return ;
				}
				dep[y]=dep[x]+1;
				if(vs[y])continue; 
				vs[y]=1;
				q.push(node{y,dep[x]+1});
			}
		}
	}
}
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int x,y;
  	cin>>n>>m;
  	for(int i=1;i<n;i++)cin>>x>>y,add(x,y,1),add(y,x,1);
	for(int i=1;i<=m;i++)cin>>x,q.push(node{x,1}),dep[x]=nm[x]=vs[x]=1;
	bfs();
	if(!flag)cout<<"NO"<<endl;
	return 0;
}

J:

告訴你a[i]的和不大於1e6 。

也就是說分段最多nlogn個。  

t=1,2,3……n。

段數:n/1+n/2+……+n/n=nlogn

查詢時一段一段的處理,即二分找到下一段。

這樣複雜度保證在nlog^2n內

具體見代碼

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e6+7;

int f[M],a[M],sm[M];
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int n,mx=0;
  	cin>>n;
  	for(int i=1;i<=n;i++)cin>>a[i],sm[i]=sm[i-1]+a[i],mx=max(mx,a[i]);
  	int q;
  	cin>>q;
  	while(q--)
  	{
  		int x;
  		cin>>x;
  		if(x<mx){
  			cout<<"Impossible"<<endl;
  			continue;
		}
  		if(f[x]){
  			cout<<f[x]<<endl;
  			continue;
		}
		int ans=0,now=0;
		while(1)
		{
			int l=now+1,r=n,tp=n;
			while(l<=r)
			{
				int mid=(l+r)/2;
				if(sm[mid]-sm[now]<=x)tp=mid,l=mid+1;
				else r=mid-1;
			}
			now=tp;
			ans++;
			if(now==n)break;
		}
		f[x]=ans;
		cout<<ans<<endl;
	}
	return 0;
}

M:

簡單的遞推。map搞一搞就行

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e3+7;

int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}

int a[M];
unordered_map<int,int>mp;
int main()
{
	ios::sync_with_stdio(false);
  	cin.tie(0);
  	int t;
  	cin>>t;
  	while(t--)
  	{
  		int n;
  		cin>>n;
  		for(int i=1;i<=n;i++)cin>>a[i];
  		ll ans=0;
  		mp.clear();
  		for(int i=1;i<=n;i++)
  		{
  			for(int j=i+1;j<=n;j++)
  			{
  				int q=a[i],w=a[j];
  				if(q==w&&mp.find(q)!=mp.end())ans+=mp[q];
  				else 
  				{
  					int c=w-q;
  					if(mp.find(q-c)!=mp.end())ans+=mp[q-c];
  				//	cout<<"====  "<<q<<"  "<<w<< "  "<<c<<"    - ";
				}
			//	cout<<i<<"  -  "<<j<<"   "<<ans<<endl;
			}
			mp[a[i]]++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章