题目链接: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. 2016.6.24——vector<vector<int>>【Binary Tree Level Order Traversal】

    Binary Tree Level Order Traversal 本题收获: 1.vector<vector<int>>的用法 vector<vector<int ...

  2. 【环境变量】Linux 下三种方式设置环境变量与获取环境变量

    1.在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似的错误. 2.那么什么是环境变 ...

  3. Hibernate5笔记6--Hibernate检索优化

    Hibernate检索优化: 检索即查询.为了减轻DB的访问压力,提高检索效率,Hibernate对检索进行了优化. 所谓检索优化,指的是对查询语句的执行时机进行了细致.严格的把控:并不是代码中一出现 ...

  4. 29 A Quick Guide to Go's Assembler 快速指南汇编程序:使用go语言的汇编器简介

    A Quick Guide to Go's Assembler 快速指南汇编程序:使用go语言的汇编器简介 A Quick Guide to Go's Assembler Constants Symb ...

  5. Python字符串(Str)详解

    字符串是 Python 中最常用的数据类型.我们可以使用引号('或")来创建字符串. 创建字符串很简单,只要为变量分配一个值即可 字符串的格式 b = "hello itcast. ...

  6. 深度学习在美团点评推荐平台排序中的应用&& wide&&deep推荐系统模型--学习笔记

    写在前面:据说下周就要xxxxxxxx, 吓得本宝宝赶紧找些广告的东西看看 gbdt+lr的模型之前是知道怎么搞的,dnn+lr的模型也是知道的,但是都没有试验过 深度学习在美团点评推荐平台排序中的运 ...

  7. JQ + CSS实现浪漫表白必备

    JQ + CSS实现浪漫表白必备页面 效果图: 图片素材 : 代码如下,复制即可使用: <!DOCTYPE html> <html> <head> <meta ...

  8. Unix IPC之Posix信号量实现生产者消费者

    采用多生产者,多消费者模型. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /**  * 生产者  */ P(nempty); P(mutex); // 写入一个 ...

  9. Qt通过ODBC来操作Excel

    示例代码: #include<QtCore/QCoreApplication> #include<QtSql> #include<QObject> #include ...

  10. 在MVC中如何使用vs2013编译调试razor cshtml

    打开mvc项目的csproj文件: <MvcBuildViews>false</MvcBuildViews> 改为 <MvcBuildViews>true</ ...