2018.8.6 Noip2018模拟测试赛(十九)
日期: |
八月六号 |
总分: |
300分 |
难度: |
提高 ~ 省选 |
得分: |
10分(MMP) |
题目目录:
T1:Tree
T2:异或运算
赛后反思:
Emmmmmmm……
一直在打第一题…… 结果考完才发现dp少了一种情况……
除此之外,我无话可说…… Emmmmmm……
题解:
T1:Tree
树形背包dp,设$f[i][j][k(0/1/2)]$为$i$的子树中,选$j$条边,0:从$i$出发,到$i$结束/1:从$i$出发,到$i$的某个后代结束/2:后代开始,经过$i$,后代结束:
状态转移:
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
这样就能树形dp,时间复杂度 $O(n^2)$
COMPLETE CODE:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; int n,k,x,y,z,tot=,h[],siz[];
long long f[][][],ans=1e18;
struct Edge{
int x,y,dis,next;
}e[];
bool vis[]; inline void add_edge(int x,int y,int z){
e[++tot].x=y,e[tot].dis=z;
e[tot].next=h[x],h[x]=tot;
} void dfs(int x,int fa){
siz[x]=;
f[x][][]=;
f[x][][]=;
for(int i=h[x];i;i=e[i].next){
if(e[i].x==fa)continue;
dfs(e[i].x,x);
int y=e[i].x;
for(int j=siz[x]-;j>=;j--)
for(int k=siz[y]-;k>=;k--){
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
f[x][j+k+][]=min(f[x][j+k+][],f[x][j][]+f[y][k][]+*e[i].dis);
}
siz[x]+=siz[e[i].x];
}
} int main(){
memset(f,0x7f,sizeof(f));
scanf("%d%d",&n,&k);
for(int i=;i<n;i++){
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
add_edge(y,x,z);
}
dfs(,-);
for(int i=;i<=n;i++)
ans=min(ans,min(f[i][k-][],f[i][k-][]));
printf("%lld",ans);
}
T2:异或运算
可持久化Trie树,我之前还不知道可持久化,现在才知道,这跟主席树是一样的,是通过差分,维护区间。
我们按位贪心,由于$n$很小,对于每一位枚举$a$序列,统计现在的位置往优了走会有多少个值,如果大于$k$,可以走,如果小于$k$,所有反着走。
问题就这么迎刃而解了。(貌似这题用动态开点的主席树维护值域也能做……)
CODE:
#include<iostream>
#include<cstdio>
using namespace std; int n,m,q,x,y,l,r,k,cnt=,tot=;
int a[],b[],root[];
struct Trie{
int siz,next[];
}v[];
struct Node{
int l,r,val;
}s[]; void insert(int &o,int last,int x){
o=++tot;
int p=o,q=last;
for(int i=;i>=;i--){
v[p]=v[q],v[p].siz++;
v[p].next[(x>>i)&]=++tot;
p=v[p].next[(x>>i)&];
q=v[q].next[(x>>i)&];
}
v[p].siz++;
} int find(int cnt,int k){
int ans=;
for(int i=;i>=;i--){
int sum=;
for(int j=;j<=cnt;j++){
bool c=(s[j].val>>i)&;
sum+=v[v[s[j].r].next[c^]].siz
-v[v[s[j].l].next[c^]].siz;
}
if(sum>=k){
ans=ans<<|;
for(int j=;j<=cnt;j++){
bool c=(s[j].val>>i)&;
s[j].r=v[s[j].r].next[c^];
s[j].l=v[s[j].l].next[c^];
}
}else{
k-=sum,ans=ans<<;
for(int j=;j<=cnt;j++){
bool c=(s[j].val>>i)&;
s[j].r=v[s[j].r].next[c];
s[j].l=v[s[j].l].next[c];
}
}
}
return ans;
} int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%d",a+i);
for(int i=;i<=m;i++)scanf("%d",b+i);
for(int i=;i<=m;i++)
insert(root[i],root[i-],b[i]);
scanf("%d",&q);
for(int i=;i<=q;i++){
scanf("%d%d%d%d%d",&x,&y,&l,&r,&k);
cnt=;
for(int j=x;j<=y;j++)
s[++cnt]=(Node){root[l-],root[r],a[j]};
printf("%d\n",find(cnt,k));
}
}
T3:Tree Restoring
很容易发现离所有点最远的点定是树的直径的两个端点。(我怎么就没想到呢?)
所有点的距离只能在$\left\lceil{d\over 2}\right\rceil$到$d$之间,同时直径上的点两两对称,判断这些即可。
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std; int n,x,a,b,t[]; int main(){
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&x);
t[x]++,a=max(a,x);
}
b=a+>>;
for(int i=b+;i<=a;i++)
if(t[i]<){
printf("Impossible");
return ;
}
if(a&){
if(t[b]<){
printf("Impossible");
return ;
}t[b]-=;
}else{
if(t[b]<){
printf("Impossible");
return ;
}t[b]-=;
}
for(int i=;i<=b;i++)
if(t[i]){
printf("Impossible");
return ;
}
printf("Possible");
}
2018.8.6 Noip2018模拟测试赛(十九)的更多相关文章
- 2018.7.31 Noip2018模拟测试赛(十六)
日期: 七月最后一天 总分: 300分 难度: 提高 ~ 省选 得分: 30分(少的可怜) 我太弱了:(题目目录) T1:Mushroom追妹纸 T2:抵制克苏恩 T3:美味 失分分析:(QA ...
- 2018.8.7 Noip2018模拟测试赛(二十)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 100分(呵呵一笑) 题目列表: T1:SS T2:Tree Game T3:二元运算 赛后反思: Emmmmmm…… 开 ...
- 2018.8.8 Noip2018模拟测试赛(二十一)
日期: 八月七号 总分: 300分 难度: 提高 ~ 省选 得分: 112分(OvO) 题目目录: T1:幸福的道路 T2:Solitaire T3:Flags 赛后心得: 第一题裸树d啊! ...
- 2017.8.2 Noip2018模拟测试赛(十八)
日期: 八月二日 总分: 300分 难度: 提高 ~ 省选 得分: 40分(又炸蛋了!!) 题目列表: T1:分手是祝愿 T2:残缺的字符串 T3:树点涂色 赛后心得: 哎,T1求期望,放弃. ...
- 2017.8.1 Noip2018模拟测试赛(十七)
日期: 八月第一天 总分: 300分 难度: 提高 ~ 省选 得分: 100分(不应该啊!) 题目目录: T1:战争调度 T2:选数 T3:由乃的OJ 赛后心得: MMP,首先第一题花了大概 ...
- [2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania
[2018冬令营模拟测试赛(二十一)]Problem A: Decalcomania 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见&quo ...
- noi2019模拟测试赛(四十七)
noi2019模拟测试赛(四十七) T1与运算(and) 题意: 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...
- EZ 2018 06 17 NOIP2018 模拟赛(十九)
这次的题目难得的水,但是由于许多哲学的原因,第二题题意表述很迷. 然后是真的猜题意了搞了. 不过这样都可以涨Rating我也是服了. Upt:链接莫名又消失了 A. 「NOIP2017模拟赛11.03 ...
- EZ 2018 06 10 NOIP2018 模拟赛(十八)
好久没写blog&&比赛题解了,最近补一下 这次还是很狗的,T3想了很久最后竟然连并查集都忘写了,然后T2map莫名爆炸. Rating爆减......链接不解释 好了我们开始看题. ...
随机推荐
- linux更新git
在CentOS中使用yum install git安装的git是1.7版本的,所以需要更新1.9以及更高版本的git. 安装方法如下: 1.安装依赖的包: yum -y install curl-de ...
- python queue - 同步队列类
参考 官网 queue 模块 queue 模块实现多生产者,多消费者队列. 当必须在 ==多个线程之间安全地交换信息== 时,它在线程编程中特别有用. 此模块中的Queue类实现了所有必需的锁定语义. ...
- DNA Pairing-freecodecamp算法题目
DNA Pairing 1.要求 DNA 链缺少配对的碱基.依据每一个碱基,为其找到配对的碱基,然后将结果作为第二个数组返回. Base pairs(碱基对)是一对 AT 和 CG,为给定的字母匹配缺 ...
- Codeforces 517 #B
http://codeforces.com/contest/1072/problem/B 开始想的只有搜索,时间复杂度$O(4^n)$,明显有问题. 想了半个小时没有思路,然后想到了正难则反,就开始步 ...
- MongoDB - 启动&连接数据库
1> 启动数据库 1.1> 依次添加如下目录: 1.1.1> mongodb-space 1.1.2> mongodb-space/conf 1.1.3> mongodb ...
- php 正则表达式中的 .*? 表示什么意思
我们知道我 .* 是任意字符,有的时候比较困惑在加个?什么意思. ?是非贪婪模式.*会匹配后面的一切字符,就是到结束的意思加?后就是不贪婪模式,这时要看?后边的字符是什么了,如.*?"的意思 ...
- 无法重启ssh
rm /dev/null mknod /dev/null c 1 3 chmod 666 /dev/null
- Java底层基础题
一.Java底层基础题 1.SpringMVC的原理以及返回数据如何渲染到jsp/html上? 答:Spring MVC的核心就是DispatcherServlet , 一个请求经过Dispatche ...
- LeetCode(242)Valid Anagram
题目 Given two strings s and t, write a function to determine if t is an anagram of s. For example, s ...
- NO_PUBKEY
* 现象:$ sudo apt-get update时警告如下: W: GPG error: http://ppa.launchpad.net precise Release: The followi ...