期望得分:100+60+70=230

实际得分:0+60+0=60

T1

可以证明如果一对括号原本就匹配,那么这对括号在最优解中一定不会被分开

所以用栈记录下没有匹配的括号

最后栈中一定是 一堆右括号然后一堆左括号

ans=栈中右括号/2 上取整 + 栈中左括号 /2 上取整

#include<cstdio>
#include<cstring> using namespace std; #define N 100001 int top;
char st[N]; char s[N]; int main()
{
freopen("shower.in","r",stdin);
freopen("shower.out","w",stdout);
scanf("%s",s+);
int len=strlen(s+);
for(int i=;i<=len;i++)
if(s[i]=='(') st[++top]='(';
else if(top && st[top]=='(') top--;
else st[++top]=')';
int ans=;
int i;
for(i=;i<=top;i++)
if(st[i]!=')') break;
i--;
printf("%d",(i+)/+(top-i+)/);
}

考试的时候 碰到右括号,没有判断此时栈顶是否是左括号

括号匹配只需要判断 栈中是否有东西,因为一定是 左括号

这里因为有不合法的情况,所以需要判断

T2

前缀和二分

#include<cstdio>
#include<iostream> #define N 1000004 using namespace std; bool vis[N];
int p[N],cnt; long long sum[N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void pre()
{
for(int i=;i<N;i++)
{
if(!vis[i])
{
p[++cnt]=i;
sum[cnt]=sum[cnt-]+p[cnt];
}
for(int j=;j<=cnt;j++)
{
if(i*p[j]>=N) break;
vis[i*p[j]]=true;
if(i%p[j]==) break;
}
}
} int main()
{
freopen("diary.in","r",stdin);
freopen("diary.out","w",stdout);
pre();
int T,n,k;
read(T);
int l,r,mid,tmp;
while(T--)
{
read(n); read(k);
l=k;r=lower_bound(p+,p+cnt+,n)-p;
tmp=-;
while(l<=r)
{
mid=l+r>>;
if(sum[mid]-sum[mid-k]<=n) tmp=mid,l=mid+;
else r=mid-;
}
printf("%d\n",tmp==- ? - : sum[tmp]-sum[tmp-k]);
}
}

60 暴力

#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; int T; #define N 1000004 typedef long long LL; int p[N],cnt;
bool vis[N]; LL sum[N]; struct node
{
int n,k,id;
}e[]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void pre()
{
for(int i=;i<N;i++)
{
if(!vis[i]) p[++cnt]=i;
for(int j=;j<=cnt;j++)
{
if(i*p[j]>=N) break;
vis[i*p[j]]=true;
if(i%p[j]==) break;
}
}
for(int i=;i<=cnt;i++) sum[i]=sum[i-]+p[i];
} namespace solve1
{
void work()
{
int n,k,m; bool ok;
for(int i=;i<=T;i++)
{
n=e[i].n; k=e[i].k;
m=lower_bound(p+,p+cnt,n)-p;
ok=false;
for(int i=m;i>=k && !ok ;i--)
if(sum[i]-sum[i-k]<=n) { printf("%d\n",sum[i]-sum[i-k]); ok=true; }
if(!ok) puts("-1");
}
}
} namespace solve2
{
int ans[]; bool cmp(node p,node q)
{
return p.k<q.k;
} void work()
{
sort(e+,e+T+,cmp);
int r=lower_bound(p+,p+cnt+,e[].n)-p;
int l=r;
int now=;
while(now<=T)
{
l=min(l,r-e[now].k+);
if(l<=) break;
while(l> && sum[r]-sum[l-]>e[now].n) r--,l--;
if(sum[r]-sum[l-]>e[now].n) break;
ans[e[now].id]=sum[r]-sum[l-];
now++;
}
for(;now<=T;now++) ans[e[now].id]=-;
for(int i=;i<=T;i++) printf("%d\n",ans[i]);
}
} void init()
{
read(T); bool flag1=true,flag2=true;
for(int i=;i<=T;i++)
{
read(e[i].n); read(e[i].k);
if(e[i].n>) flag1=false;
if(e[i].n!=e[].n) flag2=false;
e[i].id=i;
}
if(flag1 || T==) solve1::work();
else if(flag2) solve2::work();
} int main()
{
freopen("diary.in","r",stdin);
freopen("diary.out","w",stdout);
pre();
init();
}

T3 

这算个DP套DP吗

设g[i][j] 表示 在第i棵树中,所有的点到j的权值和

F(t)=F(a)+F(b)+ size[a]*size[b]*l + g[a][c]*size[b] + g[b][d]*size[a]

size在合并的过程中 维护即可

求 g[i][j] :

设dis[i][j][k] 在第i棵树中,j到k的距离

设现在要求g[t][k],有一条长为L的边连接c和d

g[t][k]=g[A][k]+g[B][d]+(L+dis[A][k][c])*size[B]

求dis[i][j][k]:

如果本就是在一棵树里,直接= dis[A][j][k]

否则

假设有一条长为L的边连接了树A中第点c和树B中的点d,构成了第t棵树

现在要求dis[t][p1][p2]

=dis[A][c][p1]+dis[B][d][p2]+L

g数组和dis数组不可能都存下来,每一次合并只涉及两个点,记忆化搜索即可

注意:如果某点是在合并的第二棵树里,编号还要减去第一棵树的大小

#include<map>
#include<cstdio>
#include<iostream>
#include<algorithm> using namespace std; typedef long long LL; const int mod=1e9+; struct node
{
int p;
LL p1,p2;
node() {}
node(int i,LL j,LL k)
{
p=i;
p1=min(j,k);
p2=max(j,k);
}
bool operator < (node a) const
{
if(p!=a.p) return p<a.p;
if(p1!=a.p1) return p1<a.p1;
return p2<a.p2;
}
}; map<pair<int,LL>,int>g;
map<node,int>dis; int id1[],id2[],len[];
LL num1[],num2[]; LL siz[]; int f[]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void read(LL &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int getDIS(int i,LL j,LL k)
{
if(!i) return ;
if(j==k) return ;
node x=node(i,j,k);
if(dis.count(x)) return dis[x];
if(j<siz[id1[i]])
{
if(k<siz[id1[i]]) return dis[x]=getDIS(id1[i],j,k);
return dis[x]=(1LL*getDIS(id1[i],num1[i],j)+len[i]+getDIS(id2[i],num2[i],k-siz[id1[i]]))%mod;
}
else
{
if(k<siz[id1[i]]) return dis[x]=(1LL*getDIS(id1[i],num1[i],k)+len[i]+getDIS(id2[i],num2[i],j-siz[id1[i]]))%mod;
return dis[x]=getDIS(id2[i],j-siz[id1[i]],k-siz[id1[i]]);
}
} int getG(int i,LL j)
{
if(!i) return ;
pair<int,LL>pr = make_pair(i,j);
if(g.count(pr)) return g[pr];
if(j<siz[id1[i]]) return g[pr]=((1LL*getDIS(id1[i],num1[i],j)+len[i])*(siz[id2[i]]%mod)%mod+getG(id2[i],num2[i])+getG(id1[i],j))%mod;
return g[pr]=((1LL*getDIS(id2[i],num2[i],j-siz[id1[i]])+len[i])*(siz[id1[i]]%mod)%mod+getG(id1[i],num1[i])+getG(id2[i],j-siz[id1[i]]))%mod;
} int main()
{
freopen("cloth.in","r",stdin);
freopen("cloth.out","w",stdout);
int m;
read(m);
siz[]=;
for(int i=;i<=m;i++)
{
read(id1[i]); read(id2[i]); read(num1[i]); read(num2[i]); read(len[i]);
f[i]=(f[id1[i]]+f[id2[i]]+(siz[id1[i]]%mod)*(siz[id2[i]]%mod)%mod*len[i]%mod+getG(id1[i],num1[i])*(siz[id2[i]]%mod)%mod+getG(id2[i],num2[i])*(siz[id1[i]]%mod)%mod)%mod;
siz[i]=siz[id1[i]]+siz[id2[i]];
cout<<f[i]<<'\n';
}
}

2017 清北济南考前刷题Day 2 afternoon的更多相关文章

  1. 2017 清北济南考前刷题Day 7 afternoon

    期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...

  2. 2017 清北济南考前刷题Day 1 afternoon

    期望得分:80+30+70=180 实际得分:10+30+70=110 T1 水题(water) Time Limit:1000ms   Memory Limit:128MB 题目描述 LYK出了道水 ...

  3. 2017 清北济南考前刷题Day 3 afternoon

    期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...

  4. 2017 清北济南考前刷题Day 4 afternoon

    期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...

  5. 2017 清北济南考前刷题Day 6 afternoon

    期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...

  6. 2017 清北济南考前刷题Day 5 afternoon

    期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...

  7. 2017 清北济南考前刷题Day 3 morning

    实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstd ...

  8. 2017 清北济南考前刷题Day 7 morning

    期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...

  9. 2017 清北济南考前刷题Day 6 morning

    T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...

随机推荐

  1. b1

    组长:吴晓晖 过去两天完成了哪些任务: 代码重构进行中,界面,预计两个beta单位完成 展示GitHub当日代码/文档签入记录 接下来的计划 更加人性化的推荐算法 还剩下哪些任务 有哪些困难 有哪些收 ...

  2. 我是IT小小鸟读后感

    <我是一只IT小小鸟>一只是我想读list中一个本,但是上次去当当买的时候,竟然缺货了...昨天监考,实在无聊,就上网看电子书了,一天就看完了,看得有点仓促,所以理解估计不深. 1.刘帅: ...

  3. 我的JAVA运算符理解

    基本概念 原码,反码,补码 只需要记住这几句就够了  1.二进制的最高位是符号位:0表示正数,1表示负数 2.正数的原码,反码,补码都一样 3.负数的反码=它的原码符号位不变,其他位取反 4.负数的补 ...

  4. windows redis 后台运行

    1. 进入 DOS窗口2. 在进入Redis的安装目录3. 输入:redis-server --service-install redis.windows.conf --loglevel verbos ...

  5. nginx配置hls

    备注:本来是想用浏览器播放hls,后来没有成功,最后使用flash播放rtmp的方案.所以下面的配置未使用. 修改/usr/local/nginx/conf/nginx.conf文件内容如下: wor ...

  6. iOS成长之路-使用系统默认声音、震动

    导入框架 代码片段 apple系统默认声音名称说明: 1.声音格式是MP3或m4r的需要转成caf格式(可先转成aif , aiff,然后修改后缀) 2.路径在/System/Library/Audi ...

  7. 基于windowsphone7的控制ppt播放

    最近突然想起了一个学长的一个利用手机控制ppt播放的一个创意,并想将其在windows phone7上实现一下. 经过几天的努力已经可以控制ppt的播放,暂停,上一张,下一张了,并且电脑会将当前ppt ...

  8. PAT 甲级 1150 Travelling Salesman Problem

    https://pintia.cn/problem-sets/994805342720868352/problems/1038430013544464384 The "travelling ...

  9. spring远程服务知识梳理

    序:本文主要是总结和归纳spring的远程服务相关知识,可作为入门学习笔记.写博客目的也是为了进行知识梳理,便于以后查看.本文主要参考资料 spring 实战第三版 本文主要讨论内容如下: 远程调度概 ...

  10. .net webapi创建接口

    最近使用webapi做了一个用户数据库接口,方便其它网站接入验证用户,实现中解决出现的一些问题,做了一些记录, 1.返回显示为json数据 2.允许其他网站访问,刚开始没有设,在本地机测试时可以访问, ...