A.

  考虑把(u,v)的询问离线挂在u上,然后dfs,每次从fath[x]到[x]相当于x子树dis区间加1,x子树以外区间-1,然后维护区间和区间平方和等。

常数略大。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxv 100500
#define maxe 200500
using namespace std;
long long n,fath[maxv],q,uu,vv,dis[maxv],l[maxv],r[maxv],times=,fdfn[maxv],g[maxv],nume=,ans[maxv],cnt;
long long tot=,root,ls[maxv<<],rs[maxv<<],val1[maxv<<],val2[maxv<<],lazy[maxv<<];
vector <long long> v[maxv],id[maxv];
bool vis[maxv];
struct edge
{
long long v,nxt;
}e[maxe];
long long read()
{
char ch;long long data=;
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='')
{
data=data*+ch-'';
ch=getchar();
}
return data;
}
void addedge(long long u,long long v)
{
e[++nume].v=v;e[nume].nxt=g[u];g[u]=nume;
e[++nume].v=u;e[nume].nxt=g[v];g[v]=nume;
}
void pushup(long long now,long long left,long long right)
{
val1[now]=val1[ls[now]]+val1[rs[now]];
val2[now]=val2[ls[now]]+val2[rs[now]];
}
void pushdown(long long now,long long left,long long right)
{
if (!lazy[now]) return;
long long mid=left+right>>,d=lazy[now],ll=mid-left+,rr=right-mid;
val1[ls[now]]+=*d*val2[ls[now]]+d*d*ll;val1[rs[now]]+=*d*val2[rs[now]]+d*d*rr;
val2[ls[now]]+=d*ll;val2[rs[now]]+=d*rr;
lazy[ls[now]]+=d;lazy[rs[now]]+=d;
lazy[now]=;
}
void build(long long &now,long long left,long long right)
{
now=++tot;lazy[now]=;
if (left==right)
{
val1[now]=dis[fdfn[left]]*dis[fdfn[left]];val2[now]=dis[fdfn[left]];
return;
}
long long mid=left+right>>;
build(ls[now],left,mid);
build(rs[now],mid+,right);
pushup(now,left,right);
}
long long ask(long long now,long long left,long long right,long long l,long long r)
{
pushdown(now,left,right);
if ((left==l) && (right==r)) return val1[now];
long long mid=left+right>>;
if (r<=mid) return ask(ls[now],left,mid,l,r);
else if (l>=mid+) return ask(rs[now],mid+,right,l,r);
else return ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+,right,mid+,r);
}
void modify(long long now,long long left,long long right,long long l,long long r,long long val)
{
if (l>r) return;
pushdown(now,left,right);
if ((left==l) && (right==r))
{
lazy[now]+=val;
val1[now]+=*val*val2[now]+val*val*(right-left+);val2[now]+=val*(right-left+);
return;
}
long long mid=left+right>>;
if (r<=mid) modify(ls[now],left,mid,l,r,val);
else if (l>=mid+) modify(rs[now],mid+,right,l,r,val);
else
{
modify(ls[now],left,mid,l,mid,val);
modify(rs[now],mid+,right,mid+,r,val);
}
pushup(now,left,right);
}
void get_ans(long long x)
{
for (long long i=;i<v[x].size();i++)
ans[id[x][i]]=ask(root,,n,l[v[x][i]],r[v[x][i]]);
}
void modify_tree(long long x,long long f)
{
modify(root,,n,l[x],r[x],-f);
modify(root,,n,,l[x]-,f);
modify(root,,n,r[x]+,n,f);
}
void dfs1(long long x)
{
l[x]=r[x]=++times;fdfn[times]=x;
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if (v!=fath[x])
{
dis[v]=dis[x]+;
dfs1(v);
r[x]=max(r[x],r[v]);
}
}
}
void dfs2(long long x)
{
get_ans(x);
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if (v!=fath[x])
{
modify_tree(v,);
dfs2(v);
modify_tree(v,-);
}
}
}
int main()
{
n=read();
for (long long i=;i<=n-;i++) {fath[i+]=read();addedge(fath[i+],i+);}
q=read();
for (long long i=;i<=q;i++)
{
uu=read();vv=read();
v[uu].push_back(vv);id[uu].push_back(i);
}
dfs1();build(root,,n);
dfs2();
for (long long i=;i<=q;i++) printf("%lld\n",ans[i]);
return ;
}

B.

  我们发现k=0的时候可以o(1)计算(毕竟是01序列)。当k>=1的时候可以证明答案是ceil(l/2)*trunc(l/2)。

要善于猜结论啊。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 500500
using namespace std;
long long n,q,a[maxn],s1[maxn],s[maxn],x[maxn],y[maxn],k[maxn],cnt[][maxn],ans[maxn],tab[maxn];
long long read()
{
char ch;long long data=;
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='')
{
data=data*+ch-'';
ch=getchar();
}
return data;
}
void calc(long long type,long long pos)
{
cnt[][]=;tab[]=;
for (long long i=;i<=n;i++)
{
cnt[][i]=cnt[][i-];cnt[][i]=cnt[][i-];
if (!s[i]) cnt[][i]++;
else cnt[][i]++;
tab[i]=tab[i-]+cnt[s[i]^][i];
}
if (!type)
{
for (long long i=;i<=n;i++)
{
if (x[i]>=) ans[i]=(cnt[][y[i]-]-cnt[][x[i]-])*cnt[][y[i]]+(cnt[][y[i]-]-cnt[][x[i]-])*cnt[][y[i]]-(tab[y[i]-]-tab[x[i]-]);
else ans[i]=cnt[][y[i]-]*cnt[][y[i]]+cnt[][y[i]-]*cnt[][y[i]]-tab[y[i]-];
}
}
}
int main()
{
n=read();q=read();
for (long long i=;i<=n;i++) {a[i]=read();s1[i]=s1[i-]^a[i];s[i]=s1[i];}
for (long long i=;i<=q;i++) {x[i]=read();y[i]=read();k[i]=read();x[i]++;y[i]++;}
calc(,);
for (int i=;i<=q;i++)
{
if (k[i])
{
long long l=y[i]-x[i]+;
ans[i]=(l/+(l&))*(l/);
}
}
for (long long i=;i<=q;i++) printf("%lld\n",ans[i]);
return ;
}

C.

  这TM的是个环套树啊。、

我们找出路径上的值,然后每次加gcd(环长,m)加到最大即可。

之前10分的原因是神TM没开long long。(我就说我怎么可能写挂这种题)(撤回)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 100500
#define maxe 200500
using namespace std;
struct edge
{
long long v,w,nxt;
}e[maxe];
long long n,g[maxv],nume=,dis1[maxv],dis2[maxv],root,father[maxv],anc[maxv][],dep[maxv];
long long r1,r2,q,s,t,m,u,v,w,a,b,x;
long long read()
{
char ch;long long data=;
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='')
{
data=data*+ch-'';
ch=getchar();
}
return data;
}
void addedge(long long u,long long v,long long w) {e[++nume].v=v;e[nume].w=w;e[nume].nxt=g[u];g[u]=nume;}
long long getfather(long long x)
{
if (x!=father[x]) father[x]=getfather(father[x]);
return father[x];
}
bool unionn(long long a,long long b)
{
long long f1=getfather(a),f2=getfather(b);
if (f1==f2) return true;
father[f1]=f2;return false;
}
void dfs(long long x,long long father)
{
for (long long i=g[x];i;i=e[i].nxt)
{
long long v=e[i].v;
if (v!=father)
{
anc[v][]=x;dep[v]=dep[x]+;
dis1[v]=dis1[x]+e[i].w;dis2[v]=dis2[x]+e[i^].w;
dfs(v,x);
}
}
}
void get_table()
{
for (long long e=;e<=;e++)
for (long long i=;i<=n;i++)
anc[i][e]=anc[anc[i][e-]][e-];
}
long long lca(long long x,long long y)
{
if (dep[x]<dep[y]) swap(x,y);
for (long long e=;e>=;e--)
if ((dep[anc[x][e]]>=dep[y]) && (anc[x][e]))
x=anc[x][e];
if (x==y) return x;
for (long long e=;e>=;e--)
{
if (anc[x][e]!=anc[y][e])
{
x=anc[x][e];
y=anc[y][e];
}
}
return anc[x][];
}
long long gcd(long long a,long long b)
{
if (!b) return a;
return gcd(b,a%b);
}
long long calc(long long x)
{
x=(x%m+m)%m;
long long f1=(r1%m+m)%m,d1=gcd(f1,m);
return (m--x)/d1*d1+x;
}
int main()
{
n=read();
for (long long i=;i<=n;i++) father[i]=i;
for (long long i=;i<=n;i++)
{
a=read();b=read();x=read();
if (unionn(a,b)) {root=a;u=a;v=b;w=x;}
else {addedge(a,b,x);addedge(b,a,-x);}
}
dfs(root,);get_table();
r1=dis1[v]-w;r2=dis2[v]+w;
q=read();
for (long long i=;i<=q;i++)
{
s=read();t=read();m=read();x=lca(s,t);
printf("%lld\n",calc(dis2[s]-dis2[x]+dis1[t]-dis1[x]));
}
return ;
}

FR #2题解的更多相关文章

  1. FR #3题解

    A. 傻逼题?...前缀和什么的随便搞搞就好了. #include<iostream> #include<cstdio> #include<cstring> #in ...

  2. FR #1题解

    A. 建图跑最小费用最大流.分类讨论每种情况如何连边,费用怎么定. #include<iostream> #include<cstdio> #include<cstrin ...

  3. SDOI2017 Round2 详细题解

    这套题实在是太神仙了..做了我好久...好多题都是去搜题解才会的 TAT. 剩的那道题先咕着,如果省选没有退役就来填吧. 「SDOI2017」龙与地下城 题意 丢 \(Y\) 次骰子,骰子有 \(X\ ...

  4. THUSC2017 Day1题解

    THUSC2017 Day1题解 巧克力 题目描述 "人生就像一盒巧克力,你永远不知道吃到的下一块是什么味道." 明明收到了一大块巧克力,里面有若干小块,排成n行m列.每一小块都有 ...

  5. Codeforces Round #545 Div1 题解

    Codeforces Round #545 Div1 题解 来写题解啦QwQ 本来想上红的,结果没做出D.... A. Skyscrapers CF1137A 题意 给定一个\(n*m\)的网格,每个 ...

  6. HNOI2018简要题解

    HNOI2018简要题解 D1T1 寻宝游戏 题意 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得这一年出题的机会. 作为 ...

  7. BJOI2018简要题解

    BJOI2018简要题解 D1T1 二进制 题意 pupil 发现对于一个十进制数,无论怎么将其的数字重新排列,均不影响其是不是 \(3\) 的倍数.他想研究对于二进制,是否也有类似的性质. 于是他生 ...

  8. NOIP2014题解

    NOIP2014题解 Day1 生活大爆炸版石头剪刀布 rps 简单模拟题,注意细节 #include<iostream> #include<cstdio> using nam ...

  9. NOIP2012题解

    NOIP2012题解 Day1 Vigenère 密码 vigenere 直接模拟就好了,对于那张表找找规律就很短了. #include<iostream> #include<cst ...

随机推荐

  1. Growing转化的每一步(笔记整理)

    渠道流量监控中,如何将劣质流量和优质流量区分开来? 劣质流量总会有有一些不同于其他正常渠道的特征,比如在同一个时间中大量集中访问.使用的硬件设备比较固定.使用特定的浏览器等. 实际案例:去年有一些 A ...

  2. 笔记2:傻瓜式盗QQ程序

    1.一个简单的盗QQ号的方法 仿做一个QQ的窗体 PS:当然里面有用的控件只有两个输入框和一个登陆按钮,其他的尽量做得像一些吧! 点登陆时的后台代码: PS:需要导入两个包:using System. ...

  3. Java 集合系列 07 List总结(LinkedList, ArrayList等使用场景和性能分析)

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  4. Linux Bash代码 利用for循环实现命令的多次执行

    Linux Bash代码 [yuanhao15@lu01 libsvm-rank-2.81]$ for ((i=0; i<=19; i++)) do ./svm-train -s 5 -c 10 ...

  5. struts2视频学习笔记 01-02

    网易云课堂-<struts2> 课时1 Struts2: WebWork2基础上发展而来,MVC框架,无侵入式设计. 提供了拦截器,类型转换器,支持多种表现层技术(JSP, freeMar ...

  6. centos6.5 64位系统安装 tengine

          1 安装pcre 下载好pcre 上传到服务器 我用的版本是pcre-8.31.tar.gz tar -zxvf pcre-8.31.tar.gz cd pcre-8.31 ./confi ...

  7. 如何创建一个客户端回调:js获得服务端的内容?

    答案:表面上看去就是前端的js调用服务的C#方法,本质就是ajax,通过XMLHttpRequest对象和服务端进行交互.回调:就说回过头来调用,按理说js是一种脚本语言,怎么能用来调用服务端的呢?就 ...

  8. 【模板下载】innosetup 制作.net安装包的模板

    NetworkComms网络通信框架序言 这个模板是在博客园和CodeProject上的代码修改而成的,感谢原作者 模板是2个 innosetup 制作.net 2.0 安装包的模板 innosetu ...

  9. 在现有 SharePoint 服务器上安装 PowerPivot for SharePoint

    步骤1: 检查 SQL Server 2008 R2 Analysis Services 实例的“程序”文件夹.如果您找到了现有安装或之前安装的证据,则执行剩余步骤.否则,直接执行步骤 2:安装 Po ...

  10. ROS TF——learning tf

    在机器人的控制中,坐标系统是非常重要的,在ROS使用tf软件库进行坐标转换. 相关链接:http://www.ros.org/wiki/tf/Tutorials#Learning_tf 一.tf简介 ...