[填坑][主线任务]历年NOIP刷题计划

今天又是喜闻乐见的非考试日,那么今天做点什么呢==

前些日子的主线任务陆陆续续(接近)完成了,好多蒙蔽的没学好的算法都算是入门补坑了

我听学长说,做题的顺序是:NOIP真题->NOIP模拟题->专项练习->杂题

啊哈!最重要的真题我还没做几道呢...于是这两天填填这个坑吧

[NOIP2016 Day1 T2]天天爱跑步

NOIP2016最难的题没有之一QAQ,原来做过一直没过,今天重新听讲解,总算打了出来

[NOIP2015 Day2 T3]运输计划

压轴题防AK,最后一个点及其凶残,并没有过去,跑了1.7s,无奈只能打表QAQ

其实打的是正解:LCA+二分答案+树上查分,可能是人傻自带超大常数T-T

95分代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define pos(i,a,b) for(int i=(a);i<=(b);++i)
#define N 301000
inline int read(){
	int sum(0);char ch=getchar();
	while(ch<‘0‘||ch>‘9‘) ch=getchar();
	while(ch>=‘0‘&&ch<=‘9‘){
		sum=sum*10+ch-‘0‘;
		ch=getchar();
	}
	return sum;
}
int n,m;
struct haha{
	int next,to,w;
}edge[N*2];
int head[N],cnt=1;
void add(int u,int v,int w){
	edge[cnt].to=v;
	edge[cnt].w=w;
	edge[cnt].next=head[u];
	head[u]=cnt++;
}
int dis[N],dis2[N],fa[N],dep[N],wei[N];
void dfs(int x){
	for(int i=head[x];i;i=edge[i].next){
		int to=edge[i].to,w=edge[i].w;
		if(to!=fa[x]){
			fa[to]=x;
			dep[to]=dep[x]+1;
			dis2[to]=dis2[x]+w;
			wei[to]=w;
			dfs(to);
		}
	}
}
int p[N][20];
void init(){
	for(int j=0;(1<<j)<=n;j++) pos(i,1,n) p[i][j]=-1;
	pos(i,1,n) p[i][0]=fa[i];
	for(int j=1;(1<<j)<=n;j++){
		pos(i,1,n) if(p[i][j-1]!=-1) p[i][j]=p[p[i][j-1]][j-1];
	}
}
int lca(int a,int b){
	if(dep[a]<dep[b]) swap(a,b);
	int i;for(i=0;(1<<i)<=dep[a];i++);i--;
	for(int j=i;j>=0;j--) if(dep[a]-(1<<j)>=dep[b]) a=p[a][j];
	if(a==b) return a;
	for(int j=i;j>=0;j--) if(p[a][j]!=-1&&p[a][j]!=p[b][j]){
		a=p[a][j];b=p[b][j];
	}
	return fa[a];
}
int cuns[N],cunt[N];
int l,r,size[N],lc[N];
void dfs2(int x){
	for(int i=head[x];i;i=edge[i].next){
		int to=edge[i].to;
		if(to!=fa[x]){
			dfs2(to);
			size[x]+=size[to];
		}
	}
}
bool check(int num){
	int temp(0),jishu(0);
	pos(i,1,n) size[i]=0;
	pos(i,1,m){
		if(dis[i]>num){
			++jishu;
			if(dis[i]-num>temp) temp=dis[i]-num;
			++size[cuns[i]];++size[cunt[i]];size[lc[i]]-=2;
		}
	}
	dfs2(1);
	pos(i,2,n){
		if(size[i]==jishu&&wei[i]>=temp) return true;
	}
	return false;
}
int main(){
	n=read();m=read();
	pos(i,1,n-1){
		int x=read(),y=read(),z=read();
		add(x,y,z);add(y,x,z);
	}
	dfs(1);
	init();
	pos(i,1,m){
		cuns[i]=read(),cunt[i]=read();
		lc[i]=lca(cuns[i],cunt[i]);
		dis[i]=dis2[cuns[i]]+dis2[cunt[i]]-2*dis2[lc[i]];
		if(dis[i]>r) r=dis[i];
	}
	while(l+1<r){
		int mid=(l+r)>>1;
		if(check(mid)) r=mid;
		else l=mid;
	}
	cout<<r<<endl;
	return 0;
}

  

时间: 2024-07-30 23:56:11

[填坑][主线任务]历年NOIP刷题计划的相关文章

BZOJ第一页刷题计划

BZOJ第一页刷题计划 已完成:1 / 100 BZOJ1000:A+B

历年NOIP水题泛做

快noip了就乱做一下历年的noip题目咯.. noip2014 飞扬的小鸟 其实这道题并不是很难,但是就有点难搞 听说男神错了一个小时.. 就是$f_{i,j}$表示在第$i$个位置高度为$j$的时候最小点击次数 递推的话对于上升的情况只做一次,后面几次在后面再做.. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace st

[填坑][主线任务]MP&amp;KMP算法

当时一直就没有理解QAQ,觉得会hash就够了,但是想到fail数组有很多神奇的妙用,于是来填这个坑 先讲MP算法: 我就直接说fail数组的含义吧(从0开始字符串下标): fail[i]表示0~i-1这个串的最长border的长度,同时也是重新开始匹配的将要匹配的那个位置下标. 举个小栗子:对于字符串 abcdabd fail[6]=2,即abcdab的最长border的长度为2(ab),匹配失败的时候,下标跳到fail[6](为2)再来匹配,即从‘c’字母开始匹配(因为前边的‘ab’已经匹配

刷题计划

我很后悔这一年来被我浪费过的每分每秒,我已经不想再浪费时间了. 平时不好好刷题还想着打比赛? 今年的目标就是刷完紫书第七章的搜索,第八章的贪心,第九章的dp,然后每次的cf补题尽量补到div2的DE题,如果时间有剩余,就学AC自动机等一些数据结构吧. 第一阶段:紫书ch7-ch9  时间11月末-12月31号 第二阶段  训练指南选择性的补充知识点,同时打一些5个小时比赛+补题  时间1月-2月 第三阶段  区域赛真题组队训练

[填坑][主线任务]Trie树

当时学过QAQ,无奈早已忘光,只剩一个概念2333 重新捡起来,同时感谢yymxw的指导(才怪) 负责任的粘贴一下网上的概念: Trie树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的.Trie树的基本性质可以归纳为: (1)根节

【不可能的任务22/200】【填坑】bzoj3224 splay裸题

人生第一道splay不出所料是一道裸题,一道水题,一道2k代码都不到的题 1 #include <cstdio> 2 int root,N=0,n,p,q; 3 int fa[100001],c[100001][2],size[100001],sp[100001]; 4 void rot(int x) 5 { 6 int y=fa[x],k=(c[y][0]==x); 7 size[y]=size[c[y][k]]+size[c[x][k]]+1;size[x]=size[c[x][!k]]+

HDU5697 刷题计划 dp+最小乘积生成树

分析:就是不断递归寻找靠近边界的最优解 学习博客(必须先看这个): 1:http://www.cnblogs.com/autsky-jadek/p/3959446.html 2:http://blog.csdn.net/u013849646/article/details/51524748 注:这里用的最小乘积生成树的思想,和dp结合 每次找满足条件的最优的点,只不过BZOJ裸题的满足条件是形成一棵树 这个题是大于m,生成树借用最小生成树进行求解最优,大于m用dp进行求解最优 #include

刷题计划(转)

原文链接:http://my.oschina.net/lee24/blog/74949 初级: 一.基本算法:      (1)枚举. (poj1753,poj2965)      (2)贪心(poj1328,poj2109,poj2586)      (3)递归和分治法.      (4)递推.      (5)构造法.(poj3295)      (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996) 二.图算法:      (1)图的深度优先遍历和

noip刷题记录 20170823

独木桥 怎么说呢 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N = 5050; int n, l, pos[N], maxx = 0, minn = 0; int main(){ scanf("%d%d", &l, &n); for(int i = 1; i <= n; i++) scanf(&qu