期望得分: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. 作业6 团队项目之需求 (NABCD模型)

     N A B C D模型分析 WorkGroup:NewApps 组员:欧其锋(201306114305  http://www.cnblogs.com/ouqifeng/) 吕日荣(20130611 ...

  2. 四则运算之GUI

    四则运算之GUI Coding克隆地址:https://git.coding.net/lvgx/pair_programming.git   目录: 一.前言 二.计划时间——PSP 三.接口设计 四 ...

  3. 重学 以太网的mac协议的CSMA/CD

    之前上课一直模糊的CSMA/CD进行系统性整理. CSMA/CD (Carrier Sense Multiple Acess/Collision Detect)应用在OSI的 数据链路层 在以太网中, ...

  4. Java网络编程一:基础知识详解

    网络基础知识 1.OSI分层模型和TCP/IP分层模型的对应关系 这里对于7层模型不展开来讲,只选择跟这次系列主题相关的知识点介绍. 2.七层模型与协议的对应关系 网络层   ------------ ...

  5. 转 webpack 插件 svg-sprite-loader

    最近开始看 Vue 了,首先用官方的模版把项目快速搭建起来: Vue.js 提供一个官方命令行工具,可用于快速搭建大型单页应用.该工具提供开箱即用的构建工具配置,带来现代化的前端开发流程.只需几分钟即 ...

  6. form表单转化json对象

    利用 $.fn 可以让每一个jquery 对象都能直接使用这个方法. //form表单转化json对象$.fn.serializeObject = function () { var o = {}; ...

  7. paperOne基于java web的简易四则运算出题网站

    项目成员:张金生     张政 需求概要 1.运算数均为正整数 2.包含的运算符有+,-,*,/ 3.除法运算结果为整除运算 4.批量生成题目并判题 核心功能分析 1.题目生成——java后端 题目生 ...

  8. 最近JavaScript的一些收获

    开发习惯的上的收获 1,开发过程中,要让整个逻辑展示在一个函数中,中间部分则做可以考虑公用策略优化 2,开发完成至少有三个角度进行测试,正面方面和中立 开发技巧上面的收获 1,驼峰转为‘-’以及‘-’ ...

  9. wamp 开启短标签支持

    1.先使用phpinfo.php文件打印出信息 2.找到Loaded Configuration File   根据他的路径去修改php.ini文件 3.打开php.ini文件,搜索 short_op ...

  10. [知乎]老狼:UFS VS NVMe

    https://zhuanlan.zhihu.com/p/26652622 最近某手机厂商的闪存门在知乎上被人踢爆,在所谓“爵士水军”和“友商水军”的口水大战中,至少eMMC, UFS等火星名词被广泛 ...