Educational Codeforces Round 33 (Rated for Div. 2)A-F
总的来说这套题还是很不错的,让我对主席树有了更深的了解
A:水题,模拟即可
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n;
cin>>n;
int p1=,p2=;
for(int i=;i<n;i++)cin>>a[i];
for(int i=;i<n;i++)
{
if(a[i]!=p1&&a[i]!=p2)
{
cout<<"NO"<<endl;
return ;
}
else
{
if(a[i]==p2)swap(p1,p2);
if(p1==)
{
if(p2==)p2=;
else p2=;
}
else if(p1==)
{
if(p2==)p2=;
else p2=;
}
else if(p1==)
{
if(p2==)p2=;
else p2=;
}
}
}
cout<<"YES"<<endl;
return ;
}
/******************** ********************/
A
B:给一个数n,找最大的n的余数是特定数,特定数是二进制前面k+1个1后面k个0的数,公式给出了,直接算出来然后从大到小遍历
这题没给公式的话可能还可以做做,不过也不难推,但是给了公式就相当水了
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; int a[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie();
for(int i=;i<=;i++)
a[i]=((<<i)-)*(<<(i-));
int n;
cin>>n;
for(int i=;i>=;i--)
{
if(n%a[i]==)
{
cout<<a[i]<<endl;
return ;
}
}
return ;
}
/******************** ********************/
B
C:找每个连通图里点权值最小相加即可,简单dfs
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; vector<int>v[N];
bool vis[N];
ll c[N],cnt;
void dfs(int u)
{
vis[u]=;
cnt=min(cnt,c[u]);
for(int i=;i<v[u].size();i++)
{
if(!vis[v[u][i]])
{
dfs(v[u][i]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n,m;
cin>>n>>m;
for(int i=;i<=n;i++)cin>>c[i];
for(int i=;i<m;i++)
{
int a,b;
cin>>a>>b;
v[a].pb(b);
v[b].pb(a);
}
ll ans=;
for(int i=;i<=n;i++)
{
if(!vis[i])
{
cnt=1e18;
dfs(i);
ans+=cnt;
}
}
cout<<ans<<endl;
return ;
}
/******************** ********************/
C
D:题意:刚开始账户里余额为0,余额不能超过k,每天早上你可以存钱,晚上有交易,可能增减,如果晚上交易为0,那么就需要查询账户,此时的账户余额不能为负数,问最少需要几天存钱,不行输出-1
题解:先求一遍前缀和,然后对前缀和求一遍后缀最大值,然后从前往后扫,每次查询到余额为负的时候就根据后缀最大值来判断,然后加上最大能加的钱数,不能就输出-1
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; ll a[N],sum[N],maxx[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie();
int n;ll d;
cin>>n>>d;
for(int i=;i<=n;i++)cin>>a[i];
for(int i=;i<=n;i++)
{
sum[i]=sum[i-]+a[i];
if(sum[i]>d)
{
cout<<-<<endl;
return ;
}
}
maxx[n+]=-1e18;
for(int i=n;i>=;i--)maxx[i]=max(maxx[i+],sum[i]);
ll cnt=,ans=;
for(int i=;i<=n;i++)
{
if(a[i]==&&sum[i]+cnt<)
{
ll x=max(d-maxx[i]-cnt,(ll));
// cout<<i<<"++++"<<x<<" "<<cnt<<" "<<maxx[i]<<" "<<d-maxx[i]-cnt<<endl;
cnt+=x;
/* if(sum[i]+cnt>d)
{
cout<<-1<<endl;
return 0;
}*/
ans++;
if(a[i]==&&sum[i]+cnt<)
{
// cout<<i<<" "<<sum[i]+cnt<<endl;
cout<<-<<endl;
return ;
}
}
else if(sum[i]+cnt>d)
{
cout<<-<<endl;
return ;
}
}
cout<<ans<<endl;
return ;
}
/********************
3 4
-5 3 0
3 5
-5 -5 0
********************/
D
E:题意:给你x,y要求y个数相乘等于x的情况数
题解:组合数,求出x的所有质因数的个数a,然后每次乘上C(y-1+a,y-1),,因为是隔板法,相当于y个盒子中放a个小球,有y-1个隔板,y-1+a个地方放y-1个隔板,所有情况就是C(y-1+a,y-1),没有放的地方就放上1,最后考虑有负数的情况,因为C(n,2)+C(n,4)+...=2^(n-1)乘上这个就好了
#include<bits/stdc++.h>
#define fi first
#define se second
#define ll long long
#define mp make_pair
#define pb push_back
#define mod 1000000007
#define pii pair<int,int>
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1 using namespace std; const int g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; ll fac[N];
ll quick(ll a,ll b)
{
ll ans=;
while(b)
{
if(b&)ans=ans*a%mod;
a=a*a%mod;
b>>=;
}
return ans;
}
int main()
{
/*ios::sync_with_stdio(false);
cin.tie(0);*/
fac[]=;
for(int i=;i<N;i++)fac[i]=fac[i-]*i%mod;
int q;
scanf("%d",&q);
while(q--)
{
ll x,y,ans=;
scanf("%lld%lld",&x,&y);
for(ll i=;i*i<=x;i++)
{
if(x%i==)
{
ll cnt=;
while(x%i==)cnt++,x/=i;
// cout<<cnt<<endl;
ll inv=quick(fac[y-]*fac[cnt]%mod,mod-);
ans=ans*fac[y-+cnt]%mod*inv%mod;
}
}
if(x!=)
{
ll cnt=;
ans=ans*y%mod;
}
printf("%lld\n",ans*quick(,y-)%mod);
}
return ;
}
/*******************
C(y-1+x,y-1)*2^(y-1)%mod;
(y-1+x)!
(y-1)!(x)!
*******************/
E
F:给你一棵树,每个节点有一个权值,q个查询每次查询x的子树中与x距离不超过k的权值最小的那个节点,强制在线
题解:主席树维护,先dfs序建树,然后按照树节点深度从小到大来插入每个点,最后查询的时候找1到d【x】+k的那颗主席树,然后查询l【x】到r【x】的最小值就是答案了
总结:主席树一般就是用来维护从1到x(x<=n)的所有区间的,可以方便的维护某一区间的权值,本质来说还是一颗线段树,主要是通过rt来访问是哪颗主席树
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod 1000000007
#define C 0.5772156649
//#define ls l,m,rt<<1
//#define rs m+1,r,rt<<1|1
#define pii pair<int,int> using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f; int a[N],d[N],l[N],r[N],num;
int maxd,pos[N],res;
int rt[N*],ls[N*],rs[N*],value[N*],tot;
vector<int>v[N];
void dfs(int u,int c,int f)
{
++num;
l[u]=num;
d[u]=c;
maxd=max(maxd,c);
for(int i=;i<v[u].size();i++)
{
int x=v[u][i];
if(x==f)continue;
dfs(x,c+,u);
}
r[u]=num;
}
void build(int &o,int l,int r)
{
o=++tot;
value[o]=1e9+;
if(l==r)return ;
int m=(l+r)>>;
build(ls[o],l,m);
build(rs[o],m+,r);
}
void update(int &o,int l,int r,int last,int p,int va)
{
o=++tot;
ls[o]=ls[last];
rs[o]=rs[last];
if(l==r)
{
value[o]=va;
return ;
}
int m=(l+r)>>;
if(p<=m)update(ls[o],l,m,ls[last],p,va);
else update(rs[o],m+,r,rs[last],p,va);
value[o]=min(value[ls[o]],value[rs[o]]);
}
int query(int o,int l,int r,int L,int R)
{
if(L<=l&&r<=R)return value[o];
int ans=1e9+;
int m=(l+r)>>;
if(L<=m)ans=min(ans,query(ls[o],l,m,L,R));
if(R>m) ans=min(ans,query(rs[o],m+,r,L,R));
return ans;
}
void bfs(int n,int root)
{
queue<int>q;
q.push(root);
res=;
while(!q.empty())
{
int u=q.front();
q.pop();
// cout<<u<<endl;
pos[d[u]]=res;//对应深度在哪颗主席树中
update(rt[res],,n,rt[res-],l[u],a[u]);
res++;
for(int i=;i<v[u].size();i++)
{
int x=v[u][i];
if(d[x]==d[u]+)q.push(x);
}
}
}
void print(int o,int l,int r)
{
cout<<l<<" "<<r<<" "<<value[o]<<endl;
if(l==r)return ;
int m=(l+r)>>;
print(ls[o],l,m);
print(rs[o],m+,r);
}
int main()
{
/*ios::sync_with_stdio(false);
cin.tie(0);*/
int n,root;
scanf("%d%d",&n,&root);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
v[a].pb(b);
v[b].pb(a);
}
num=tot=;
dfs(root,,-);
/* for(int i=1;i<=n;i++)
cout<<l[i]<<" "<<r[i]<<" "<<d[i]<<endl;*/
build(rt[],,n);
// print(rt[0],1,n);
bfs(n,root);
/* for(int i=1;i<=n;i++)
printf("%d\n",pos[i]);*/
int q,last=;
scanf("%d",&q);
while(q--)
{
int x,k;
scanf("%d%d",&x,&k);
x=((x+last)%n)+,k=(k+last)%n;
k=k+d[x];k=min(k,maxd);
last=query(rt[pos[k]],,n,l[x],r[x]);
printf("%d\n",last);
}
return ;
}
/********************
5 2
1 3 2 3 5
2 3
5 1
3 4
4 1
2
1 2
2 3
********************/
F
Educational Codeforces Round 33 (Rated for Div. 2)A-F的更多相关文章
- Educational Codeforces Round 33 (Rated for Div. 2) E. Counting Arrays
题目链接 题意:给你两个数x,yx,yx,y,让你构造一些长为yyy的数列,让这个数列的累乘为xxx,输出方案数. 思路:考虑对xxx进行质因数分解,设某个质因子PiP_iPi的的幂为kkk,则这个 ...
- Educational Codeforces Round 33 (Rated for Div. 2) F. Subtree Minimum Query(主席树合并)
题意 给定一棵 \(n\) 个点的带点权树,以 \(1\) 为根, \(m\) 次询问,每次询问给出两个值 \(p, k\) ,求以下值: \(p\) 的子树中距离 \(p \le k\) 的所有点权 ...
- Educational Codeforces Round 33 (Rated for Div. 2) 题解
A.每个状态只有一种后续转移,判断每次转移是否都合法即可. #include <iostream> #include <cstdio> using namespace std; ...
- Educational Codeforces Round 33 (Rated for Div. 2) D. Credit Card
D. Credit Card time limit per test 2 seconds memory limit per test 256 megabytes input standard inpu ...
- Educational Codeforces Round 33 (Rated for Div. 2) C. Rumor【并查集+贪心/维护集合最小值】
C. Rumor time limit per test 2 seconds memory limit per test 256 megabytes input standard input outp ...
- Educational Codeforces Round 33 (Rated for Div. 2) B. Beautiful Divisors【进制思维/打表】
B. Beautiful Divisors time limit per test 2 seconds memory limit per test 256 megabytes input standa ...
- Educational Codeforces Round 33 (Rated for Div. 2) A. Chess For Three【模拟/逻辑推理】
A. Chess For Three time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Educational Codeforces Round 33 (Rated for Div. 2)
A. Chess For Three time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- Educational Codeforces Round 33 (Rated for Div. 2) D题 【贪心:前缀和+后缀最值好题】
D. Credit Card Recenlty Luba got a credit card and started to use it. Let's consider n consecutive d ...
随机推荐
- 001-maven下载jar后缀为lastUpdated问题
问题简述 Maven在下载仓库中找不到相应资源时,网络中断等,会生成一个.lastUpdated为后缀的文件.如果这个文件存在,那么即使换一个有资源的仓库后,Maven依然不会去下载新资源. 解决方案 ...
- LeetCode:为运算表达式设置优先级【241】
LeetCode:为运算表达式设置优先级[241] 题目描述 给定一个含有数字和运算符的字符串,为表达式添加括号,改变其运算优先级以求出不同的结果.你需要给出所有可能的组合的结果.有效的运算符号包含 ...
- rails 下载 send_file
def download send_file File.join(Rails.root, "public", @doc.link), :filename => @title+ ...
- Yii2 自定义独立验证器
新建一个文件: ?php /** * author : forecho <caizhenghai@gmail.com> * createTime : 2015/7/1 14:54 * de ...
- ZOJ 3961 Let's Chat 【水】
题目链接 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3961 题意 给出两个人的发消息的记录,然后 如果有两人在连续M天 ...
- second application:use an arcgis.com webmap
<!DOCTYPE html> <html> <head> <title>Create a Web Map</title> <meta ...
- MySQL数据文件介绍及存放位置
怎样查看MySql数据库物理文件存放位置? 使用命令行查找: show global variables like '%datadir%'; 我查找的位置:C:\ProgramData\MySQL\M ...
- class_alias--为一个类创建别名
class_alias--为一个类创建别名 bool class_alias ( string $original , string $alias [, bool $autoload = TRUE ] ...
- 优美的英文诗歌Beautiful English Poetry
<When you are old>——<当你老了> --- William Butler Yeats ——威廉·巴特勒·叶芝When you are old and grey ...
- Kubernetes lxcfs
容器实现的基础是NameSpace和Cgroups. NameSpace实现了对容器(进程)的隔离,NameSpace技术实际上修改了应用进程看待整个计算机“视图”,也就是作用域,即它的“视线”被操作 ...