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;
}