题目链接:https://codeforces.com/contest/985

’A.Chess Placing

题意:给了一维的一个棋盘,共有n(n必为偶数)个格子。棋盘上是黑白相间的。现在棋盘上有n/2个棋子,让你全部移动到黑色格子或者白色格子,要求步数最少,并输出步数。

题解:由于黑色或者白色都是固定位置,我们对棋子位置排个序,然后全部移动到任意一个颜色,取两个最小步数的最小值就好了。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
const int N=1e5+;
int a[N],p[N];
int n,d,ans1,ans2;
int main()
{
scanf("%d",&n);
ans1=ans2=;
n/=;
for(int i=;i<=n;i++)
scanf("%d",p+i);
sort(p+,p+n+);
for(int i=;i<=n;i++)
{
ans1+=abs(p[i]-i*);
ans2+=abs(p[i]-(i*-));
}
printf("%d\n",min(ans1,ans2));
return ;
}

B.Switches and Lamps

题意:有n个开关和m盏灯,每个开关都关联一些灯,按下该开关后这些关联的灯如果亮着就保持不变,关着就会亮起。问你存不存在n-1个开关的组合,使得按下这n-1个开关后,所有灯全部亮起。

题解:用0和1标记按下开关i后第j个灯是否亮起。然后求每个灯关联的开关数。接着遍历所有开关。如果存在一组开关,使得他对每个灯的亮起标记数全部小于每个灯的关联开关数,则存在这样一个组合,这个组合是除他以外的其他所有开关。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
const int N=2e3+;
int a[N],b[N],n,m;
string s[N];
bool flag;
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
cin>>n>>m;
for(int i=;i<=n;i++)
{
cin>>s[i];
for(int j=;j<m;j++)
{
if(s[i][j]=='')
a[j+]++;
}
}
for(int i=;i<=n;i++)
{
clr(b);
flag=;
for(int j=;j<m;j++)
if(s[i][j]=='')
b[j+]++;
for(int j=;j<=m;j++)
if(b[j]==a[j])
{
flag=;
break;
}
if(flag==)
return !printf("YES\n");
}
return !printf("NO\n");
}

C.Liebig's Barrels

题意:给你n*k块木板,要你做n个桶,每个桶由k块木板组成。每个桶的盛水量由最短的木板决定。让你最大化这n个木桶的总盛水量,并且每每对木桶的盛水量差不超过l。

题解:给所有板从小到大排个序,然后看最短板往上n块板是不是都小于等于其长度+l,如果不满足则做不出这样的桶组合。现在我们取n块板来造这n个木桶,作为每个桶的最短板。先算其长度+l的木板所在的位置t,然后从第一块最短板开始,每隔k个取一块板,直到板位置超过了t。然后从t位置往前取,除了前面取过的位置,一个一个地取板。按照上述操作取板,直到取了n块板作为木桶的最短板。这时候盛水量就为这n块板长度和。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
const int N=1e5+;
int a[N],b[N],n,m,k,l,t,pp;
LL ans;
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
cin>>n>>k>>l;
m=n*k;
for(int i=;i<=m;i++)
cin>>a[i];
sort(a+,a+m+);
if(a[n]-a[]>l)
{
cout<<<<endl;
return ;
}
t=upper_bound(a+,a+m+,a[]+l)-a;
ans=;
t--;
pp=;
for(int i=;i<=t && pp<n;i+=k)
ans+=1LL*a[i],pp++;
for(int i=t;i>= && pp<n;i--)
{
if(i%k==)
continue;
else
ans+=1LL*a[i],pp++;
}
printf("%I64d\n",ans);
return ;
}

D.Sand Fortress

题意:给你无穷个点,从左到右为0,1,2,3…+∞。然后给你n块积木往点上放,要求所有相邻两个点间的积木高度差不超过1。并且约束第一堆积木的高度最大值。问你把这n块积木分配到这些点上后,有放积木的点的数量最少为多少?

题解:如果要求第一堆积木数量最大为1,我们可以想象我们如果要放积木到k堆上积木数最大的情况是形成一个小山一样的,相邻堆差为1的情况。那现在我们约束了第一堆最大高度为h,我们要造k堆。那么积木数最大时,我们第一堆右侧的情况,就是(k+h-1)这个小山中第k堆(包含第k堆)左侧的小山翻转过来的样子。那么我们要求更小的积木数时,就可以通过从上到下拿走积木构成,因此k堆的可达成的积木数是0~这个最大值。对于本题,我们二分查找构成的堆数,用上述方法判断该堆能不能放n个积木,来找到堆数最小值。

此题还需要一点高精度。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 100000000
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
LL n,h,lt,rt;
LL mid;
LL t[],k[];
void mul(LL *a,LL p)
{
LL g[],ans[];
clr(g);
clr(ans);
g[]=p%mod;
p/=mod;
g[]=p%mod;
p/=mod;
g[]=p%mod;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
ans[i+j]+=g[j]*a[i];
}
for(int i=;i<;i++)
ans[i+]+=ans[i]/mod,ans[i]%=mod;
for(int i=;i<;i++)
a[i]=ans[i];
return ;
}
void add(LL *a,LL p)
{
LL g[];
clr(g);
g[]=p%mod;
p/=mod;
g[]=p%mod;
p/=mod;
g[]=p%mod;
for(int i=;i<;i++)
a[i]=a[i]+g[i];
for(int i=;i<;i++)
a[i+]+=a[i]/mod,a[i]%=mod;
return ;
}
void sub(LL *a,LL *b)
{
for(int i=;i<;i++)
{
a[i]-=b[i];
if(a[i]<)
a[i]+=mod,a[i+]--;
}
return ;
}
bool cmp(LL *a,LL p)
{
LL g[];
clr(g);
g[]=p%mod;
p/=mod;
g[]=p%mod;
p/=mod;
g[]=p%mod;
for(int i=;i>=;i--)
if(a[i]>g[i]) return true;
else if(a[i]<g[i]) return false;
return true;
}
int main()
{
scanf("%I64d%I64d",&n,&h);
lt=;
rt=n;
while(rt-lt>)
{
clr(t);
t[]=;
mid=lt+rt>>;
if(mid<=h)
mul(t,((mid+)%==?(mid+)/:(mid+))),mul(t,mid%==?mid/:mid);
else
{
if((mid+h-)&)
mul(t,(mid+h-)/),mul(t,(mid+h+)/),add(t,(mid+h-)/+);
else
mul(t,(mid+h-)/),mul(t,(mid+h+)/);
clr(k);
k[]=;
mul(k,h%==?h/:h);
mul(k,(h-)%==?(h-)/:(h-));
sub(t,k);
}
if(cmp(t,n))
rt=mid;
else
lt=mid;
}
printf("%I64d\n",rt);
return ;
}

E.Pencils and Boxes

题意:给你n个数字,让你把他们随意分配到任意数量的集合里,要求集合内数字的个数不小于k,并且任意两个数字之差不大于d。问是否能找到这样的一种集合构造。

题解:我们仍旧把数字排个序,可知每个集合包含排序后的一段连续数字。然后从后往前dp,dp他是不是能成为某个集合左端点(最小数字)。如果该数字为集合左端点,则该位置标记1,否则标记0。处理到第i个数字时,我们lower_bound出他的值+d的数字位置t,然后看看[i+k,t+1]位置有没有左端点,如果有,那么该位置也能成为左端点,标记1。由于这个区间可能很大,我们写个最大值线段树来查询这个位置区间。最后如果1能成为左端点,那么说明存在这样的集合构造,否则不存在。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
const int N=5e5+;
int n,k,d;
int a[N];
struct node
{
int l,r,maxn;
}tree[N<<];
void init(int i,int l,int r)
{
tree[i]=(node){l,r,};
if(l==r) return ;
int mid=l+r>>;
init(ls(i),l,mid);
init(rs(i),mid+,r);
return ;
}
void upd(int i,int pos,int val)
{
if(tree[i].l==tree[i].r) {tree[i].maxn=val; return ; }
int mid=tree[i].l+tree[i].r>>;
if(mid>=pos) upd(ls(i),pos,val);
else upd(rs(i),pos,val);
tree[i].maxn=max(tree[ls(i)].maxn,tree[rs(i)].maxn);
return ;
}
int qy(int i,int l,int r)
{
if(tree[i].l>=l && tree[i].r<=r) return tree[i].maxn;
int mid=tree[i].l+tree[i].r>>;
int ans=;
if(l<=mid) ans=max(ans,qy(ls(i),l,r));
if(r>mid) ans=max(ans,qy(rs(i),l,r));
return ans;
}
int main()
{
scanf("%d%d%d",&n,&k,&d);
for(int i=;i<=n;i++)
scanf("%d",a+i);
sort(a+,a+n+);
init(,,n);
for(int i=n-k+;i>=;i--)
{
int t=upper_bound(a+,a+n+,a[i]+d)-a;
t--;
if(t==n) {upd(,i,); continue;}
if(i+k>t+) continue;
upd(,i,qy(,i+k,t+));
}
if(qy(,,)==) printf("YES\n");
else printf("NO\n");
return ;
}

F.Isomorphic Strings

题意:给你一个字符串s,然后q个询问。每个询问给出两个该串的子串(长度相同),问能否对每个字母找到一个双射f(x),使得子串1能够通过双射f(x)变成子串2,子串2能通过f(x)反函数f'(x)变为子串1。

题解:我们把26个字母拆开来,如果该位置有该字母则标1,否则标0,对该字符串做26个字母的双hash。然后询问时,我们对每个询问子串h1,看其内所有出现过的字母在h2里有没有一样的标记序列(hash值)。如果都有那么说明存在这样的双射。如果其中有一个没有那么则不存在。

为什么双hash? 因为有个大佬造了一组数据卡单hash里的ull情况orz。真的是很强。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
using namespace std;
const int N=2e5+;
const int maxn=2e5;
const LL mod[]={,};
LL bit[N][];
LL rk[N][][],num[N][];
int n,m,t,h1,h2,len;
char s[N];
bool flag,rflag;
int main()
{
bit[][]=bit[][]=;
for(int i=;i<=maxn;i++)
for(int j=;j<;j++)
bit[i][j]=(bit[i-][j]<<)%mod[j];
scanf("%d%d",&n,&m);
scanf("%s",s+);
for(int i=;s[i];i++)
{
t=s[i]-'a';
for(int j=;j<;j++)
{
for(int k=;k<;k++)
if(t==j)
rk[i][j][k]=(rk[i-][j][k]<<|)%mod[k];
else
rk[i][j][k]=(rk[i-][j][k]<<)%mod[k];
if(t==j)
num[i][j]=num[i-][j]+;
else
num[i][j]=num[i-][j];
}
}
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&h1,&h2,&len);
rflag=;
for(int j=;j<;j++)
if(num[h1+len-][j]>num[h1-][j])
{
flag=;
for(int k=;k<;k++)
{
if(((rk[h1+len-][j][]-rk[h1-][j][]*bit[len][]%mod[])%mod[]+mod[])%mod[]==((rk[h2+len-][k][]-rk[h2-][k][]*bit[len][]%mod[])%mod[]+mod[])%mod[] && ((rk[h1+len-][j][]-rk[h1-][j][]*bit[len][]%mod[])%mod[]+mod[])%mod[]==((rk[h2+len-][k][]-rk[h2-][k][]*bit[len][]%mod[])%mod[]+mod[])%mod[] )
{
flag=;
break;
}
}
if(flag==)
{
rflag=;
break;
}
}
if(rflag)
printf("YES\n");
else
printf("NO\n");
}
return ;
}

G.Team Players

题意:给出数字0~(n-1),并给出m个数字对,要求你找出所有的三元组(a,b,c),a<b<c,并且其中不能包含这些数字对。然后让你输出所有三元组A*a+B*b+C*c的和。

题解:我们用容斥定理,把所有三元组和求出来,减去包含至少包含其中一个数字对的三元组的和,加上至少包含其中两个数字对的三元组的和,减掉包含其中三个数字对的三元组的和。最后一个情况要找三元环,通过了大佬的写法才知道怎么有技巧的暴力查找这样的三元环orz。

由于要mod 2^64,直接用ull去做就好了。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define INF 0x3f3f3f3f
#define LL long long
#define pb push_back
#define pbk pop_back
#define ls(i) (i<<1)
#define rs(i) (i<<1|1)
#define mp make_pair
#define ull unsigned long long
#define fi first
#define se second
using namespace std;
const int N=2e5+;
ull a,b,c,ans;
vector<int> e[N];
vector<pair<int,int> > pe;
vector<int> g[N];
int n,m,k,t,u,v,r,d;
int sz[N];
ull calc(int p0,int p1,int p2)
{
int st[]={p0,p1,p2};
sort(st,st+);
return a*st[]+b*st[]+c*st[];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie();
cout.tie();
cin>>n>>m;
cin>>a>>b>>c;
ans=;
for(int i=;i<n;i++)
{
ans+=a*i*((ull)(n--i)*(n--i)/);
ans+=b*i*i*(n--i);
ans+=c*i*((ull)i*(i-)/);
}
pe.pb(mp(,));
for(int i=;i<=m;i++)
{
cin>>u>>v;
e[u].pb(v);
e[v].pb(u);
pe.pb(mp(u,v));
if(u>v) swap(u,v);
ans-=(a*u+b*v)*(n--v)+c*((ull)(v+n)*(n--v)/);
ans-=(a*u+c*v)*(v-u-)+b*((ull)(u+v)*(v-u-)/);
ans-=(b*u+c*v)*u+a*((ull)(u-)*u/);
}
for(int i=;i<n;i++)
{
r=;
sz[i]=e[i].size();
sort(e[i].begin(),e[i].end());
for(int j=;j<sz[i];j++)
{
d=e[i][j];
if(d<i)
ans+=a*d*(sz[i]--j)+b*d*j,r++;
else
ans+=b*d*(sz[i]--j)+c*d*j;
}
ans+=a*i*((ull)(sz[i]-r)*(sz[i]-r-)/)+b*i*r*(sz[i]-r)+c*i*((ull)r*(r-)/);
}
for(int i=;i<=m;i++)
{
u=pe[i].fi;
v=pe[i].se;
if(sz[u]>sz[v] || (sz[u]==sz[v] && u>v)) swap(u,v);
g[u].pb(v);
}
for(int i=;i<n;i++)
sort(g[i].begin(),g[i].end());
for(int i=;i<=m;i++)
{
u=pe[i].fi;
v=pe[i].se;
auto p0=g[u].begin();
auto p1=g[v].begin();
while(p0!=g[u].end() && p1!=g[v].end())
if(*p0==*p1) ans-=calc(u,v,*p0),p0++,p1++;
else if(*p0<*p1) p0++;
else p1++;
}
cout<<ans<<endl;
return ;
}

Educational Codeforces Round 44 (Rated for Div. 2)的更多相关文章

  1. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  2. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://code ...

  3. Educational Codeforces Round 44 (Rated for Div. 2) F - Isomorphic Strings

    F - Isomorphic Strings 题目大意:给你一个长度为n 由小写字母组成的字符串,有m个询问, 每个询问给你两个区间, 问你xi,yi能不能形成映射关系. 思路:这个题意好难懂啊... ...

  4. [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和)

    [Educational Codeforces Round 81 (Rated for Div. 2)]E. Permutation Separation(线段树,思维,前缀和) E. Permuta ...

  5. Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - C. Magic Ship Time Limit: 2000 mSec P ...

  6. Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems(动态规划+矩阵快速幂)

    Problem   Educational Codeforces Round 60 (Rated for Div. 2) - D. Magic Gems Time Limit: 3000 mSec P ...

  7. Educational Codeforces Round 43 (Rated for Div. 2)

    Educational Codeforces Round 43 (Rated for Div. 2) https://codeforces.com/contest/976 A #include< ...

  8. Educational Codeforces Round 35 (Rated for Div. 2)

    Educational Codeforces Round 35 (Rated for Div. 2) https://codeforces.com/contest/911 A 模拟 #include& ...

  9. Educational Codeforces Round 63 (Rated for Div. 2) 题解

    Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...

随机推荐

  1. 【译】第八篇 SQL Server代理使用外部程序

    本篇文章是SQL Server代理系列的第八篇,详细内容请参考原文 在这一系列的上一篇,学习了如何用SQL Server代理作业活动监视器监控作业活动和查看作业历史记录.在实时监控和管理SQL Ser ...

  2. 【C++】数组-二分法查找

    1.原理 对于给定值的查找,如果大于该数组的中间元素,下一步在元素值大的区域继续与其中间元素比较:否则下一步在元素值小的区域内继续查找,直到找到目标元素.如果到最后还没有找到,则输出"数组中 ...

  3. scp加端口号

    scp -P 21110 root@192.168.0.1:/home/abc.txt root@192.168.0.2:/root 注意: 参数-P 的位置一定要紧跟在scp命令后面 参数-P 指的 ...

  4. Task多线程进行多进程

    using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Sys ...

  5. strcpy unsigned char

    http://bbs.csdn.net/topics/250068243 char *strcpy(char* dest, const char *src); 用unsigned char编译会出错 ...

  6. 使用离线包部署kubernetes 1.9.0、kubernetes-dashboard 1.8

    =============================================== 2018/3/22_第2次修改                       ccb_warlock 更新 ...

  7. Session和Cookie,Django的自动登录机制

    什么是Cookie? Cookie是浏览器的本地存储机制,存储服务器返回的各种信息,下次发起请求时再发送给服务端,比如访问baidu 什么是Session? 刚才说道,Cookie存储服务端返回的信息 ...

  8. 2016-2017-2 20155309南皓芯《java程序设计》第七周学习总结

    教材学习内容总结 Lambda 一种匿名方法 表达式构成 括号以及括号里用逗号分隔的参数列表 仅有一个参数的可以省略括号 ->符号 花括号以及花括号里的语句 仅有一条语句时可以省略花括号,并且这 ...

  9. 20165333实验三 敏捷开发与XP实践

    实验内容 一.参考 http://www.cnblogs.com/rocedu/p/6371315.html#SECCODESTANDARD 安装alibaba 插件,解决代码中的规范问题. 在IDE ...

  10. Adapter 适配器

    意图 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 动机 在软件开发中,有的时候系统的数据和行为都正确,但接口不符合,我们应 ...