TJOI2015 day2解题报告
TJOI2015终于写完啦~~~
T1:[TJOI2015]旅游
描述:(BZ没题面只能口述了。。)一个人在一棵树上走,每次从a->b会进行一次贸易(也就是在这条路径上买入物品然后在后面卖出)然后每次经过一个点该点的物品价格会上涨v,求每次贸易的最大获利
很裸的一道树链剖分,就是题目描述太不明白了。。这样就是在某条路径上找到某个点减去后面路径的最小点的值的最大值。可以用线段树的区间合并解决。就是在求答案时的合并答案上方向搞反了查了很久。。。以前也犯过着种错误,以后不能再犯了。。
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 50010
vector<int> e[maxn];
#define pb push_back
int add[maxn],pre[maxn],fa[maxn],pos[maxn];
int n;
inline void bfs() {
static int q[maxn],s[maxn],ch[maxn];
q[]=;
for (int l=,r=,u=q[l];l<=r;u=q[++l])
for (int i=;i<e[u].size();i++)
if (e[u][i]!=fa[u]) {
fa[e[u][i]]=u;
q[++r]=e[u][i];
}
for (int i=n,u=q[n];i;u=q[--i]) {
s[u]++;
s[fa[u]]+=s[u];
ch[fa[u]]=s[ch[fa[u]]]<s[u]?u:ch[fa[u]];
}
int cnt=;
for (int i=,u=q[];i<=n;u=q[++i]) {
if (add[u]!=) continue;
pos[add[u]=++cnt]=u;pre[u]=u;
for (u=ch[u];u;u=ch[u]) {
pos[add[u]=++cnt]=u;pre[u]=pre[fa[u]];
}
}
}
typedef long long ll;
struct b {
ll mx,mn,ans[];
b() {mx=mn=ans[]=ans[]=;}
};
inline b update(b l,b r) {
b ans;
ans.mx=max(l.mx,r.mx);
ans.mn=min(l.mn,r.mn);
ans.ans[]=max(max(l.ans[],r.ans[]),l.mx-r.mn);
ans.ans[]=max(max(l.ans[],r.ans[]),r.mx-l.mn);
return ans;
}
inline b rec(b x) {
swap(x.ans[],x.ans[]);
return x;
}
struct node {
int l,r,lz;b bo;
}t[maxn*];
#define lc (x<<1)
#define rc (lc^1)
#define mid ((l+r)>>1)
int a[maxn];
void build(int x,int l,int r){
t[x].l=l,t[x].r=r;
if (l==r) {
t[x].bo.mx=t[x].bo.mn=a[pos[l]];
t[x].bo.ans[]=t[x].bo.ans[]=;
return ;
}
build(lc,l,mid);build(rc,mid+,r);
t[x].bo=update(t[lc].bo,t[rc].bo);
}
inline void pb(int x) {
if (t[x].lz==) return ;
if (t[x].l!=t[x].r) {
t[lc].lz+=t[x].lz;
t[lc].bo.mn+=t[x].lz;
t[lc].bo.mx+=t[x].lz;
t[rc].lz+=t[x].lz;
t[rc].bo.mn+=t[x].lz;
t[rc].bo.mx+=t[x].lz;
}
t[x].lz=;
}
inline b change(int x,int x1,int y1,int z) {
int l=t[x].l,r=t[x].r;
pb(x);
if (x1<=l&&r<=y1) {
t[x].lz+=z;
t[x].bo.mn+=z;
t[x].bo.mx+=z;
return t[x].bo;
}
b ans;
if (mid>=y1) ans=change(lc,x1,y1,z);
else if (mid<x1) ans=change(rc,x1,y1,z);
else ans=update(change(lc,x1,y1,z),change(rc,x1,y1,z));
t[x].bo=update(t[lc].bo,t[rc].bo);
return ans;
}
inline b set(int x,int y,int z) {
int c[]={x,y};
b ans[];
bool bo[]={,};
while (c[]!=c[]) {
int l=add[c[]]<add[c[]]?:;
if (pre[c[l]]==pre[c[l^]]) {
if (bo[l]) ans[l]=update(change(,add[c[l^]]+,add[c[l]],z),ans[l]);
else ans[l]=change(,add[c[l^]]+,add[c[l]],z);
c[l]=c[l^];
} else {
if (bo[l]) ans[l]=update(change(,add[pre[c[l]]],add[c[l]],z),ans[l]);
else ans[l]=change(,add[pre[c[l]]],add[c[l]],z);
c[l]=fa[pre[c[l]]];
}
bo[l]=;
}
b _ans=change(,add[c[]],add[c[]],z);
if (bo[]) _ans=update(rec(ans[]),_ans);
if (bo[]) _ans=update(_ans,ans[]);
return _ans;
}
int main(){
freopen("travel.in","r",stdin);
freopen("travel.out","w",stdout);
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",a+i);
for (int i=;i<n;i++) {
int x,y;
scanf("%d%d",&x,&y);
e[x].pb(y);e[y].pb(x);
}
bfs();
build(,,n);
int Q;
scanf("%d",&Q);
while (Q--) {
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
b ans=set(x,y,v);
printf("%d\n",ans.ans[],ans.ans[],ans.mx,ans.mn);
}
return ;
}
T2:[TJOI2015]棋盘
就是一道状态压缩+矩阵乘法。
首先我们可以先状压一下,可以发现每次的转移都是相同的,然后就能用矩阵乘法优化了
CODE:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned int uint;
struct mat{
uint t[][];
mat(){memset(t,,sizeof(t));}
}d,I;
int m,n,p,k,w,a[][];
mat operator *(mat x,mat y) {
mat ans;
for (int i=;i<m;i++)
for (int j=;j<m;j++)
for (int k=;k<m;k++)
ans.t[i][j]+=x.t[i][k]*y.t[k][j];
return ans;
}
mat operator ^ (mat x,int y) {
mat ans=I;
for (;y;y>>=) {
if (y&) ans=ans*x;
x=x*x;
}
return ans;
}
inline bool check(int x,int y){
static bool b[][];
memset(b,,sizeof(b));
for (int i=;i<w;i++) b[][i]=x&(<<i);
for (int i=;i<w;i++) b[][i]=y&(<<i);
for (int i=;i<;i++)
for (int j=;j<w;j++) {
if (!b[i][j]) continue;
for (int u=;u<;u++)
for (int v=;v<p;v++)
if (a[u][v]&&(u!=||v!=k)) {
int x=i+u-,y=j+v-k;
if (x>=&&x<&&y>=&&y<w&&b[x][y]) return ;
}
}
return ;
}
int main(){
freopen("chessboard.in","r",stdin);
freopen("chessboard.out","w",stdout);
scanf("%d%d%d%d",&n,&w,&p,&k);
for (int i=;i<;i++)
for (int j=;j<p;j++) scanf("%d",a[i]+j);
m=<<w;
for (int i=;i<m;i++) I.t[i][i]=;
for (int i=;i<m;i++)
for (int j=;j<m;j++)
d.t[i][j]=check(i,j);
cout<<(d^n+).t[][]<<endl;
return ;
}
这个嘛。。。先贴下官方题解吧
好复杂对吧,我们打个表 。。。
f[1]=1/1,f[2]=3/3,f[3]=6/5,f[4]=10/7 ...
找到了吧 f[n]=n*(n+1)/2/(2n-1)。
完了。。。
CODE:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int main(){
int n;
scanf("%d",&n);
printf("%.9lf\n",n*1ll*(n+)/*1.0/(*n-));
return ;
}
话说BZ 350道题了。。。其实这一年几乎都在学校的oj上刷,能在这1年的时间刷多了100道题也挺自豪的。。。想想自己100时的那种兴奋,还是觉得自己挺弱智的。。。
还有3个小时就是自己的17岁生日了,回想自己的第16个年头,还是挺满意的,至少自己坚持了自己的路。在这里祝自己生日快乐,在接下来的一年里会接受越来越大的挑战,或者省队都进不了直接滚粗,或者noi胸牌滚粗,又或者侥幸成为了进队爷。。。不管自己今后咋样,希望能不忘本心吧,自己选择的路,就算跪着也要走完。
距GDOI还有4天,明天就是最后的一场模拟赛了,自己却感觉还总是找不到感觉,真的不想再发生像NOIP还有GDKOI时那黑暗的第二天了。。。自己真的很想被人敬仰膜拜一番,加油吧,再认真仔细一点吧。
以后的路会怎样,就跟我现在在听的歌一样吧。God knows,只有上帝才会知道,我们现在所能做的,只有认真过好每一分每一秒了
GDOI,God Bless!!!
TJOI2015 day2解题报告的更多相关文章
- GX/GZOI2019 day2 解题报告
GX/GZOI2019 day2 解题报告 题目链接 逼死强迫症 旅行者 旧词 t1 逼死强迫症 显然地,记 \(f(i)\) 为长度为 \(i\) 的木板的答案,可得: \(\\\) \[f(i)= ...
- 【NOIP2015】提高day2解题报告
题目: P1981跳石头 描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石.组委会已经选择好了两块岩石作为比赛起点和终点.在起点和终点之间,有 N ...
- 【未完成0.0】Noip2012提高组day2 解题报告
第一次写一套题的解题报告,感觉会比较长.(更新中Loading....):) 题目: 第一题:同余方程 描述 求关于x的同余方程ax ≡ 1 (mod b)的最小正整数解. 格式 输入格式 输入只有一 ...
- NOIp2016 Day1&Day2 解题报告
Day1 T1 toy 本题考查你会不会编程. //toy //by Cydiater //2016.11.19 #include <iostream> #include <cstd ...
- 常州培训 day2 解题报告
第一题: 题目大意: 给出一个M面的骰子,投N次,求最大期望值. 最大期望值的定义: 比如M=2,N=2, 那么 2次可以是 1,1,最大值为1: 1,2最大值为2: 2,1最大值为2: 2,2 最大 ...
- TJOI2015 day1解题报告
博客园的编辑器真的是太蛋疼了= =,想用tex然后上jpg又贴不了链接,真的很纠结啊= = T1:[TJOI2015]线性代数 描述:戳上面吧= = 首先这道题我觉得是这套题最漂亮的一道题了(虽然说学 ...
- 洛谷 P3975 [TJOI2015]弦论 解题报告
P3975 [TJOI2015]弦论 题目描述 为了提高智商,ZJY开始学习弦论.这一天,她在<String theory>中看到了这样一道问题:对于一个给定的长度为\(n\)的字符串,求 ...
- NOIP2018提高组Day2 解题报告
前言 关于\(NOIP2018\),详见此博客:NOIP2018学军中学游记(11.09~11.11). \(Day2\)的题目和\(Day1\)比起来,真的是难了很多啊. \(T1\):旅行(点此看 ...
- CH Round #55 - Streaming #6 (NOIP模拟赛day2)解题报告
T1九九归一 描述 萌蛋在练习模n意义下的乘法时发现,总有一些数,在自乘若干次以后,会变成1.例如n=7,那么5×5 mod 7=4,4×5 mod 7=6,6×5 mod 7=2,2×5 mod 7 ...
随机推荐
- 集群下Cookie共享,必须要设置machineKey
这个节允许你设置用于加密数据和创建数字签名的服务器特定的密钥.ASP.NET自动使用它来保护表单验证Cookie,你也可以将它用于受保护的视图状态数据.同时,这个密钥还用于验证进程外的会话状态提供程序 ...
- A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万
A股暴跌三日市值蒸发4.2万亿 股民人均浮亏超2万 http://finance.qq.com/a/20150508/010324.htm?pgv_ref=aio2015&ptlang=205 ...
- onethink微博插件雏形记
2014年7月30日 17:08:44 后台微博插件: 一.功能: 1.绑定微博 2.发布的文章自动发布到新浪微博 3.插件独立性强,修改地方少 二.效果: 插件目录 工程地址:http://down ...
- UVa 11495 - Bubbles and Buckets
题目大意:给一个有n个数的序列,通过交换相邻的逆序数使这个序列最终有序,求需要交换的次数. 本来可以用冒泡排序解决,但是n达到105,用冒泡排序会超时,用O(nlogn)的归并排序可以达到要求.< ...
- java求两个集合的差集
public static void main(String[] args) {Set set = new HashSet();Set set1 = new HashSet();set.add(&qu ...
- UVa 11129 - An antiarithmetic permutation
题目大意:给一个正整数n,构造一个0...n-1的排列,使得这个排列的任何一个长度大于2的子序列都不为等差数列. 把序列按照奇偶位置分成两个序列,这样在两个序列间就不会形成等差数列了,然后再对这两个序 ...
- UVa 10382 - Watering Grass
题目大意:有一条长为l,宽为w的草坪,在草坪上有n个洒水器,给出洒水器的位置和洒水半径,求能浇灌全部草坪范围的洒水器的最小个数. 经典贪心问题:区间覆盖.用计算几何对洒水器的覆盖范围简单处理一下即可得 ...
- mui中文在线手册及教程文档
http://dev.dcloud.net.cn/mui/ui/index.html#mask http://ask.dcloud.net.cn/question/2403 http://ask.dc ...
- AngularJS 讲解五, Factory ,Service , Provider
一. 首先说一下,为什么要引入Factory,Service和Provider这三个Service层. 1.因为我们不应该在controller层写入大量的业务逻辑和持久化数据,controller层 ...
- vmwvare 网卡设置讲解