题目链接: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. GRUB (简体中文)

    原文链接:https://wiki.archlinux.org/index.php/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87) 前言 引导程序是计算机启动时 ...

  2. 关于Unix/Linux的终端、伪终端、控制台和shell

    历史是什么:是过去传到将来的回声,是将来对过去的反映. ——雨果(法)<笑面人> 阅读本文大概需要花费你15分钟 文章导航: 计算机的发展 UNIX系统的诞生 UNIX系统的发展 终端与控 ...

  3. [转]CNN 中千奇百怪的卷积方式大汇总

    https://www.leiphone.com/news/201709/AzBc9Sg44fs57hyY.html 推荐另一篇很好的总结:变形卷积核.可分离卷积?卷积神经网络中十大拍案叫绝的操作. ...

  4. 2016.6.26——Maximum Depth of Binary Tree

    Maximum Depth of Binary Tree 本题收获 1.树时使用递归 2.注意边界条件时输出的值,仔细阅读题意,若是面试时,问清边界条件. 题目: Given a binary tre ...

  5. 【比赛游记】THUWC2019酱油记

    往期回顾:THUSC2018酱油记 day 0 早上 7 点的动车,不知道是从哪儿到哪儿的(雾),只知道从福建到广东 233333 一个值得思考的问题:福建人会不会被广东人吃啊? 动车上玩空洞骑士,可 ...

  6. imperva 更改web界面的密码

    通过SSH作为用户根登录到MX(或通过另一个用户并提升) 运行命令“su oracle” //首先切换到oracle用户 sqlplus secure/(密码)   /用此命令登录到数据库     s ...

  7. 用C代码简要模拟实现一下RPC(远程过程调用)并谈谈它在代码调测中的重要应用【转】

    转自:http://blog.csdn.net/stpeace/article/details/44947925 版权声明:本文为博主原创文章,转载时请务必注明本文地址, 禁止用于任何商业用途, 否则 ...

  8. 使用ubifs格式的根文件系统

    配置内核,使其支持ubifs文件系统 1)Device Drivers  --->Memory Technology Device (MTD) support  --->UBI - Uns ...

  9. ASP.NET MVC 防止跨站请求伪造(CSRF)攻击的方法

    在HTTP POST请求中,我们多次在View和Controller中看下如下代码: View中调用了Html.AntiForgeryToken(). Controller中的方法添加了[Valida ...

  10. Django中HttpRequest和HttpResponse

    请求和响应对象 Django中通过使用请求和响应对象来传递系统的状态. 当请求一个页面的时候,Django就创建一个HttpRequest对象,它包含了关于请求的元数据对象,然后Django加载适当的 ...