Karen and Morning

水题 注意进位即可

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int a,b;
bool pal()
{
if((a%10)==(b/10)&&(a/10)==(b%10))return true;
else return false;
} void add()
{
b+=1;
while(b>=60)b-=60,a+=1;
while(a>=24)a-=24;
}
int main()
{
char c;
scanf("%d%c%d",&a,&c,&b);
int ans=0;
while(!pal())
{
add();
ans++;
}
printf("%d\n",ans);
return 0;
}

  

Karen and Coffee

用线段树维护是显而易见的

不过由于先添加了所有点才进行所有询问,也就是说不会动态改变数据 所以用线段树是大材小用了。

用线性的方法也可以维护 这里只给出线段树代码。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e7,R=200000;
int size[N],adn[N],n,k,q;
vector<int>num;
void pushdown(int cur)
{
adn[cur*2]+=adn[cur];
adn[cur*2+1]+=adn[cur];
adn[cur]=0;
}
void add(int cur,int ln,int rn,int l,int r)
{
if(l<=ln&&r>=rn){adn[cur]++;return ;}
int mid=(ln+rn)>>1;
pushdown(cur);
if(l<=mid)add(cur*2,ln,mid,l,min(mid,r));
if(r>mid)add(cur*2+1,mid+1,rn,max(mid+1,l),r);
} void update(int cur,int ln,int rn)
{
if(ln==rn)
{
if(adn[cur]>=k)size[cur]=1;
else size[cur]=0;
return ;
}
pushdown(cur);
int mid=(ln+rn)>>1;
update(cur*2,ln,mid);
update(cur*2+1,mid+1,rn);
size[cur]=size[cur*2]+size[cur*2+1];
} void que(int cur,int ln,int rn,int l,int r,int& anss)
{
if(l<=ln&&r>=rn){anss+=size[cur];return ;}
int mid=(ln+rn)>>1;
if(l<=mid)que(cur*2,ln,mid,l,min(mid,r),anss);
if(r>mid)que(cur*2+1,mid+1,rn,max(l,mid+1),r,anss);
}
int main()
{//freopen("t.txt","r",stdin);
scanf("%d%d%d",&n,&k,&q);
int l,r;
for(int i=0;i<n;i++)
{
scanf("%d%d",&l,&r);
add(1,1,R,l,r);
}
update(1,1,R);
for(int i=0;i<q;i++)
{
int anss=0;
scanf("%d%d",&l,&r);
que(1,1,R,l,r,anss);
printf("%d\n",anss);
}
return 0;
}

C Karen and Game

很简单的贪心。。放在C的位置有点过于简单了吧(虽然我被Hack了 不过是打字失误。。mdzz)

提交前还是应该一行一行过一遍。。

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=200;
int num[N][N];
int n,m;
vector<int>co,ro;
int suma,sumb;
void row()
{
for(int i=0;i<n;i++)
{
int miv=num[i][0];
for(int j=1;j<m;j++)
miv=min(miv,num[i][j]);
for(int j=0;j<m;j++)
num[i][j]-=miv;
sumb+=miv*m;
for(int k=0;k<miv;k++)
ro.push_back(i);
}
}
void col()
{
for(int i=0;i<m;i++)
{
int miv=num[0][i];
for(int j=1;j<n;j++)
miv=min(miv,num[j][i]);
for(int j=0;j<n;j++)
num[j][i]-=miv;
sumb+=miv*n;
for(int k=0;k<miv;k++)
co.push_back(i);
}
} int main()
{//freopen("t.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&num[i][j]),suma+=num[i][j];
if(n>m){col();row();}
else {row();col();}
if(suma!=sumb){printf("-1\n");return 0;}
printf("%d\n",(int)ro.size()+(int)co.size());
for(int i=0;i<ro.size();i++)
printf("row %d\n",ro[i]+1);
for(int i=0;i<co.size();i++)
printf("col %d\n",co[i]+1);
return 0;
}

  

D Karen and Test

技巧性很强的一道计数题 我们考虑计算每个数对答案的贡献 即它的系数

观察发现 某个数的系数c 是它下一行的相邻两个数的系数的线性组合 是不是有点像组合数C(n,m)的递推公式 C(n,m)=C(n-1,m-1)+C(n-1,m)

我们大胆猜测该系数是某种组合数的形式

运用归纳法发现了公式

另外发现了一个特点,当n=4k+1时 第一次进行加法和第一次进行减法的结果是相同的!(也可以用归纳法证明)

所以,对于输入数据,我们首先进行几次暴力运算,将它转化为n=4k+1的形式 之后我们套用系数公式即可。

做计数问题真的是要大胆猜想啊!!! 这道题猜到是组合数就离答案很近了!

#include <bits/stdc++.h>
#define MAXN 200010
using namespace std;
const int mod=1e9+7;
int n,a[MAXN]; long long q_pow(long long x,long long n)
{
long long res=1,tmp=x;
while(n){
if(n&1) res=res*tmp%mod;
tmp=tmp*tmp%mod;
n>>=1;
}
return res;
} int main()
{
int i,j,c=1;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
while(n%4!=1){
for(i=1;i<n;i++){
if(c) a[i]=(a[i]+a[i+1])%mod;
else a[i]=(a[i]-a[i+1]+mod)%mod;
c^=1;
}
n--;
}
long long p=n/2,C=1,ans=0;
for(i=0;i<=p;i++){
if(i) C=C*(p-i+1)%mod*q_pow(i,mod-2)%mod;
//cout<<C<<endl;
ans+=C*a[i<<1|1];
ans%=mod;
}
cout<<ans<<endl;
return 0;
}

 补充证明一下:为什么当n=4k+1时有很好的性质呢? 比如n=5的三角形题目也给出了 那么当n=4*2+1=9时 实际上是由5个n=5时的三角形部分重叠构成的!

    在这个基础上 所有的归纳证明都好办了。

E Karen and Supermarket 

很有趣的一道树形DP 题目给我们的所有商品显然构成了以商品1为根的树

我们首先转化问题 考虑买j个商品的最小花费,然后枚举判断即可。

那么 我们设函数f[i][j]表示 在子树i中购买j个商品可以使用优惠券的最小花费(即保证购买了商品i且使用了i的优惠券)

 g[i][j] 表示在子树i中购买j个商品不可以使用优惠券的最小花费

转移方法是比较简单的,对于当前节点i 每次添加一个它的儿子(子树),枚举在新的子树中购买k个商品,在之前添加的所有子树中购买j-k个商品即可。

__________________________________________________________________________________

那么问题来了 这个转移的复杂度到底是多少?

先说结论,看似总的是三层循环,应该是O(n^3)实际复杂度是O(n^2)

为什么呢? 这里采用反证法证明

假如三层循环的上界都是 关于n的一次函数(不妨设 an,bn,cn) 此时满足总的复杂度O(n^3)

但是,由于最外层循环添加了 an个子树(a是任意正实数 满足an为整数) 最内层循环每次添加了cn个节点

即有an个子树,且存在一个子树有cn个节点,那么总的节点数就成了acn^2  意味着节点数不是O(n)而是O(n^2)出现矛盾

所以三层循环不可能出现每层循环的上界都为n的一次函数的情况 即复杂度是n^3的无穷小。那么其幂函数部分必然是O(n^2)

#include<bits/stdc++.h>
#include<vector>
#define N 5005
using namespace std;
const int oo=(1<<30)-1;
vector<int> G[N];
int n,m,sz[N],a[N],b[N],f[N][N],g[N][N],h[N];
void dfs(int t)
{
int i,j,k,x; sz[t]=1;
for(i=1;i<=n;i++) f[t][i]=g[t][i]=oo;
f[t][1]=a[t]-b[t];
g[t][0]=0,g[t][1]=a[t];
for(i=0;i<G[t].size();i++){
dfs(x=G[t][i]);
for(j=1;j<=sz[t];j++) h[j]=f[t][j];
for(j=1;j<=sz[t];j++)
for(k=1;k<=sz[x];k++)
f[t][j+k]=min(f[t][j+k],h[j]+min(f[x][k],g[x][k]));
for(j=0;j<=sz[t];j++) h[j]=g[t][j];
for(j=0;j<=sz[t];j++)
for(k=1;k<=sz[x];k++)
g[t][j+k]=min(g[t][j+k],h[j]+g[x][k]);
sz[t]+=sz[x];
}
}
int main()
{
int i,x;
scanf("%d %d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d %d",&a[i],&b[i]);
if(i>1) scanf("%d",&x),G[x].push_back(i);
}
dfs(1);
for(i=1;i<=n;i++)
if(min(f[1][i],g[1][i])>m) break;
cout<<i-1;
return 0;
}

  

蛤蛤 这个复杂度分析是不是很有趣? 看代码吧

Codeforces round 419 div2 补题 CF 816 A-E的更多相关文章

  1. codeforces round 422 div2 补题 CF 822 A-F

    A I'm bored with life 水题 #include<bits/stdc++.h> using namespace std; typedef long long int LL ...

  2. codeforces round 421 div2 补题 CF 820 A-E

    A Mister B and Book Reading  O(n)暴力即可 #include<bits/stdc++.h> using namespace std; typedef lon ...

  3. codeforces round 418 div2 补题 CF 814 A-E

    A An abandoned sentiment from past 水题 #include<bits/stdc++.h> using namespace std; int a[300], ...

  4. codeforces round 417 div2 补题 CF 812 A-E

    A Sagheer and Crossroads 水题略过(然而被Hack了 以后要更加谨慎) #include<bits/stdc++.h> using namespace std; i ...

  5. codeforces round 416 div2 补题 CF 811 A B C D E

    A. Vladik and Courtesy 水题略过 #include<cstdio> #include<cstdlib> #include<cmath> usi ...

  6. codeforces round 420 div2 补题 CF 821 A-E

    A Okabe and Future Gadget Laboratory 暴力 #include<bits/stdc++.h> using namespace std; typedef l ...

  7. Educational Codeforces Round 23 A-F 补题

    A Treasure Hunt 注意负数和0的特殊处理.. 水题.. 然而又被Hack了 吗的智障 #include<bits/stdc++.h> using namespace std; ...

  8. codeforces 447 A-E div2 补题

    A DZY Loves Hash 水题 #include<iostream> #include<cstdio> #include<cstdlib> #include ...

  9. 【前行】◇第3站◇ Codeforces Round #512 Div2

    [第3站]Codeforces Round #512 Div2 第三题莫名卡半天……一堆细节没处理,改一个发现还有一个……然后就炸了,罚了一啪啦时间 Rating又掉了……但是没什么,比上一次好多了: ...

随机推荐

  1. 最长回文(hdu 3068)

    Problem Description 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度.回文就是正反读都是一样的字符串,如aba, abba等 Input 输入有 ...

  2. 【ZJOI2017 Round1练习&BZOJ4766】D1T2 文艺计算姬(Prufer编码)

    题意:给定一个一边点数为n,另一边点数为m,共有n*m条边的带标号完全二分图K_{n,m},求其生成树个数 mod p. 100%的数据:1 <= n,m,p <= 10^18 思路:这是 ...

  3. msp430项目编程14

    msp430中项目---电子测重系统 1.hx711工作原理 2.电路原理说明 3.代码(显示部分) 4.代码(功能实现) 5.项目总结 msp430项目编程 msp430入门学习

  4. 洛谷——P1265 公路修建

    P1265 公路修建 题目描述 某国有n个城市,它们互相之间没有公路相通,因此交通十分不便.为解决这一“行路难”的问题,政府决定修建公路.修建公路的任务由各城市共同完成. 修建工程分若干轮完成.在每一 ...

  5. 从 modCount 看 java集合 fail-fast 机制

    一.背景 在常见的Java的非线程安全集合类中(如HashMap.ArrayList),经常可以在一些修改结构的操作(如Add)中看到实例变量 modCount++ ,来统计集合的修改次数. 从注释也 ...

  6. python执行系统命令的几种方法

    (1) os.system 这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息. import os os.system('cat /pro ...

  7. c++多线程编程:常见面试题

    题目:子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码 子线程与主线程必有一个满足条件(flag == ...

  8. eclipse环境下无法创建android virtual Devices(AVD)问题解决的方法汇总

    首先,要在eclipse环境下成功的创建一个安卓虚拟机,须要有三项东西,第一就是eclipse,第二就是android SDK Manager,第三就是ADT,也就是eclipse环境下的一个安卓虚拟 ...

  9. POJ 1436 Horizontally Visible Segments(线段树)

    POJ 1436 Horizontally Visible Segments 题目链接 线段树处理染色问题,把线段排序.从左往右扫描处理出每一个线段能看到的右边的线段,然后利用bitset维护枚举两个 ...

  10. Python - 多次检查后缀名(endwith)

    在通过后缀名查找类型文件的时候, 多次使用endwith, 使用元组(tuple), 简化操作. 此类方式, 也能够应用于if语句多次类似检測. 代码 # 列出目录内全部代码 def list_dic ...