由于蒟弱目前还没调出T1和T2,所以先写T3和T4。(T1T2更完辣! update in 6.12 07:19

T3 大佬


题目描述:

他发现katarina大佬真是太强了,于是就学习了一下katarina大佬的做题方法。

比如这是一本有n道题的练习册,katarina大佬每天都会做k道题。

第一天做第1~k题,第二天做第2 ~k+1 题……第n 天做第n-k+1 ~n 道题。

但是辣鸡 ljh 又不想太累,所以他想知道katarina大佬做完这本练习册的劳累度。

每道题有它的难度值,假设今天katarina大佬做的题目中最大难度为t,那么今天katarina大佬的劳累度就是wt?,做完这本书的劳累值就是每天的劳累值之和。

但是辣鸡ljh一道题都不会,自然也不知道题目有多难,他只知道题目的难度一定在1~m之间随机。

他想让即将参加 NOIP 的你帮他算算katarina大佬做完这本书的劳累值期望


看到是期望题,直接就跳了,回头看才知道这么水,没一会就想到正解了,奈何莫得时间了,淦。

设\(f[i]\)表示这\(k\)道题中,\(i\)是最大难度的概率。

则\(f1=(1/m)^k\),\(f2=(2/m)^k-(1/m)^k\),\(fm=1-((m-1)/m)^k\)

于是求得概率后,一天期望的贡献就是\(\sum_{i=1}^{m}w[i]*f[i]\).最后乘上总共的天数就是答案。

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
namespace EMT
{
int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
#define F(i, a, b) for (register int i = a; i <= b; i++)
#define f(x) for (register int i = head[x], j; i; i = e[i].next)
#define pf printf
inline void pi(long long x)
{
pf("%lld ", x);
}
inline void pn() { printf("\n"); }
inline void ps(int a[], int size)
{
F(i, 1, size)
pi(a[i]);
pn();
}
#define int long long
const int mod=1000000007,N=510;
int ans,n,m,k;
inline int ksm(int a,int b){
int ans=1;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}return ans;
}
int w,pre,one,now,inv;
inline signed main(){
n=read();m=read();k=read();
if(k>n){pi(0);return 0;}
F(i,1,m){
w=read();
now=ksm(i%mod,k);
one+=w*(now-pre+mod)%mod;
one%=mod;
pre=now;
}pi(one*(n-k+1)%mod*ksm(ksm(m,k),mod-2)%mod);
}
} // namespace EMT
signed main() { return EMT::main(); }

逆元最后再运算&&ksm(b&1)!!!

T4 宝藏


题目描述:


总觉得在哪里见过,原来是蓝书

但正解可忘得一干二净了,还是考场上想出的正解,结果转移时没转移全,痛失85pts

设\(f[i][s]\)表示以\(i\)为根,状态\(s\)用位运算表示已统计过的点,其中\(i\)可以用滚动数组滚掉。

用辅助数组\(len[s][k]\)表示状态为\(s\)时\(k\)距离根节点的距离,然后dp式子就显然了。

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
namespace EMT
{
int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9')
{
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
#define F(i, a, b) for (register int i = a; i <= b; i++)
#define pf printf
inline void pi(int x)
{
pf("%d ", x);
}
inline void px(int x)
{
int ans[15]={0,0,0,0,0,0}, co = 0;
while (x)
{
ans[++co] = x & 1;
x >>= 1;
}
for (int i = 4; i >= 1; i--)
pf("%d", ans[i]);
pf(" ");
}
inline void pn() { printf("\n"); }
inline void ps(int a[], int size)
{
F(i, 1, size)
pi(a[i]);
pn();
}
const int N = 14, maxn = 50000000;
int n, m, f[1 << N], w[N][N], a[N][N], len[1 << N][N];
signed main()
{
//freopen("d.out","w",stdout);
n = read();
m = read();
F(i, 1, n)
F(j, 1, n)
if (i != j)
w[i][j] = maxn;
F(i, 1, m)
{
int x = read(), y = read();
if (x == y)
{
read();
continue;
}
if (w[x][y] != maxn)
w[y][x] = w[x][y] = min(w[x][y], read());
else
w[y][x] = w[x][y] = read(), a[x][++a[x][0]] = y, a[y][++a[y][0]] = x;
}
int ans = maxn;
F(root, 1, n)
{
F(i,1,(1<<n)-1)f[i]=maxn;
memset(len, 0, sizeof(len));
f[1 << (root - 1)] = 0;
len[1 << (root - 1)][root] = 1;
F(i, 1, (1 << n) - 1)
{
//if(root==1)px(i),pi(f[i]),pn();
if(f[i]!=maxn){
F(j, 1, n)
{
if (i & (1 << (j - 1)))
{
F(k, 1, a[j][0])
{
if (!(i & (1 << (a[j][k] - 1))))
{
if(f[i | (1 << (a[j][k] - 1))]>f[i] + w[j][a[j][k]] * len[i][j]){
F(l,1,n)len[i | (1 << (a[j][k] - 1))][l]=len[i][l];
len[i | (1 << (a[j][k] - 1))][a[j][k]] = len[i][j] + 1;
f[i | (1 << (a[j][k] - 1))] = f[i] + w[j][a[j][k]] * len[i][j];
}
}
}
}
}
}
}
ans = min(ans, f[(1 << n) - 1]);
}
pi(ans);
return 0;
}
} // namespace EMT
signed main() { return EMT::main(); }

T1 辣鸡

好具有嘲讽属性的名称。。。

题目描述:

辣鸡ljh NOI之后就退役了,然后就滚去学文化课了。

然而在上化学课的时候,数学和化学都不好的ljh却被一道简单题难住了,受到了大佬的嘲笑。

题目描述是这样的:

在一个二维平面上有一层水分子,请问形成了多少个氢键?

这个二维平面可以看做一个类似棋盘的东西,每个格子可以容纳一个水分子,左下角的格子为(0,0),这个格子右边的格子为(1,0),上方格子为(0,1),以此类推。

辣鸡ljh当然不会做了,所以他来求助JeremyGou,JeremyGou一眼就看穿了真相,并想用这道题来考一考正在做NOIP模拟赛的你。

注:在本题中,我们认为一个水分子能与和它曼哈顿距离为2且直线距离小于2的其他格子形成氢键。


简洁大法万岁!

将多个操作按x排序,\(l\),\(r\),为二者交集,\(ll\),\(rr\)为二者并集,

分情况讨论即可。

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
namespace EMT
{
#define int long long
int read(){int x = 0, f = 1;char ch = getchar();
while (ch < '0' || ch > '9'){if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return x * f;
}
#define F(i, a, b) for (register int i = a; i <= b; i++)
#define f(x) for (register int i = head[x], j; i; i = e[i].next)
#define pf printf
inline void pi(long long x)
{
pf("%lld ", x);
}
inline void pn() { printf("\n"); }
inline void ps(bool a[], int size)
{
F(i, 1, size)
pi(a[i]);
pn();
}
const int N = 1e5 + 100;
int n, ans, maxl, maxh;
int maxx, maxy;
struct ques
{
int x1, y1, x2, y2;
}q[N];
inline bool com(ques a, ques b)
{
if (a.x1 == b.x1)return a.x2 < b.x2;
else return a.x1<b.x1;
}
inline int size(int x,int y,int X,int Y){
return (Y-y)*(X-x)*2;
}
inline void s(){pf("shit\n");}
inline void getans(int a,int b){
int lx1=q[a].x1,rx1=q[a].x2,ly1=q[a].y1,ry1=q[a].y2;
int lx2=q[b].x1,rx2=q[b].x2,ly2=q[b].y1,ry2=q[b].y2;
if(ry1+1==ly2||ry2+1==ly1)
{
int l=max(lx1,lx2),ll=min(lx1,lx2);
int rr=max(rx1,rx2),r=min(rx1,rx2);
if(l>r+1)return;
if(l==r+1){ans++;return;}
if(l<=r)ans+=2*(r-l);
if(l>ll)ans++;if(r<rr)ans++;
}
if(rx1+1==lx2)
{
int l=max(ly1,ly2),ll=min(ly1,ly2);
int r=min(ry1,ry2),rr=max(ry1,ry2);
if(l>r+1)return;
if(l==r+1){ans++;return;}
if(l<=r)ans+=2*(r-l);
if(l>ll)ans++;if(r<rr)ans++;
}
}
signed main()
{
n = read();
F(i, 1, n)q[i].x1=read()+1,q[i].y1=read()+1,q[i].x2=read()+1,q[i].y2=read()+1;
F(i,1,n)ans+=size(q[i].x1,q[i].y1,q[i].x2,q[i].y2);
sort(q+1,q+n+1,com);
//pi(ans);s();s();pn();
F(i,1,n)F(j,i+1,n)if(q[j].x1-q[i].x2>1)break;else getans(i,j);
pi(ans);
return 0;
}
} // namespace EMT
signed main() { return EMT::main(); }
/*
10
0 10 0 10
0 8 0 9
0 0 7 0
0 2 9 2
0 3 10 7
1 8 8 9
4 10 8 10
8 0 9 1
9 8 10 8
10 0 10 2
*/

T2 模板


题目描述:

辣鸡ljh NOI之后就退役了,然后就滚去学文化课了。

他每天都被katarina大神虐,仗着自己学过一些姿势就给katarina大神出了一道题。

有一棵 \(n\) 个节点的以 1 号节点为根的树,每个节点上有一个小桶,节点\(u\)上的小桶可以容纳\(k_{u}\)个小球,ljh每次可以给一个节点到根路径上的所有节点的小桶内放一个小球,如果这个节点的小桶满了则不能放进这个节点,在放完所有小球之后就企图去刁难katarina大神,让katarina大神回答每个节点的小桶内的小球有多少种颜色。

然而katarina大神一眼就秒掉了,还说这就是一道傻逼模板题。

现在katarina大神想考考即将参加NOIP2019的你能不能回答上辣鸡ljh的问题。

第一行,一个整数n,树上节点的数量。

接下来n ? 1行,每行两个整数u, v,表示在u, v之间有一条边。

接下来一行n个整数, ~ 表示每个节点上的小桶数量。

下一行是一个整数m,表示ljh进行的操作数量。

接下来m行,每行两个整数x, c,分别表示进行操作的节点和小球颜色。

下一行是一个整数Q,表示你需要回答的询问数。

接下来Q行,每行一个整数x,表示一个询问。


本来昨天就能A掉的,结果没考虑到负数的情况,快读直接跳过负号,

导致连WA n次的惨烈局面。(话说要是我不看测试点还要调多久啊。。。

教训:以后打快读不能偷懒为了卡一点小常数忽略负号了。

本题让我对\(splay\)的认识加深了许多。

首先是以修改时间为下标,修改时记录上每个点的时间,查询时查询时间区间就行了。

另外,对于每个点一开始都建一个\(splay\),其中包含\(root\)和一个\(map\)记录是否出现过这种小球。

当修改时先只修改最子叶的\(splay\),因为下面有着\(dfs\),可以将子树的状态合并到父节点上

至于合并的方法,是启发式合并,以前一直以为这是个什么特别厉害的东西,其实就是暴力把所有子树上的节点按照传统方式插入到父节点上...(父节点:size较大的点;

子结点:size小,插入简便的点——和\(splay\)上的父节点、子结点区分开来,这么说来,其实线段树也可以这么做吧

于是我们就可以在\(dfs\)的时候预处理出每个结点的答案,查询时直接输出即可。

\(splay\)和\(map\)的结合应用\(get\sqrt{}\)

还有,对于每个结点有一个\(rec\)数组,相当于记录了该节点在哪一颗\(splay\)树上,

在合并时如果合并到子树上就更改父亲的\(rec\),而合并到父亲上就不用更改了,因为子树的答案已经统计完了,修改\(rec\)只会浪费一点时间。

\(splay\)的中序遍历\(get\sqrt{}\)(因为左子树时间小,右子树时间大,父节点时间位于二者之间,所以按照左—父—右的顺序插入。

到这里蒟弱的思路就发表完毕了,下面是code:

Code

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
namespace EMT
{
#define F(i,a,b) for(register int i=a;i<=b;i++)
const int N=1e5+100;
inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
struct node{
int son[2],tim,size,cnt,val,fa,col;
}t[N<<2];
int head[N],co,num,ans1,rec[N],n,m,q,now;
struct edge{int next,to;}e[N<<1];
inline void add(int next,int to){e[++co].next=head[next],e[co].to=to,head[next]=co;}
struct tree{
map<int,int>mp;
int root;
inline int siz(){return t[root].size;}
inline int get(int x){return t[t[x].fa].son[1]==x;}
inline void up(int x){t[x].size=t[t[x].son[1]].size+t[t[x].son[0]].size+1;t[x].cnt=t[t[x].son[1]].cnt+t[t[x].son[0]].cnt+t[x].val;}
inline void res(int x){
int old=t[x].fa,oldf=t[old].fa,k=get(x);
t[old].son[k]=t[x].son[k^1];
t[t[x].son[k^1]].fa=old;
t[x].son[k^1]=old;t[old].fa=x;
if(oldf)t[oldf].son[t[oldf].son[1]==old]=x;
t[x].fa=oldf;
up(old);up(x);
}
inline void splay(int x){
for(register int fa;(fa=t[x].fa);res(x))
if(t[fa].fa)res(get(fa)==get(x)?fa:x);
root=x;
}
inline void insert(int tim,int col,int val){
int f=0,x=root;bool bg;
while((!bg)||(x&&t[x].tim!=tim))bg=1,f=x,x=t[x].son[tim>t[x].tim];
x=++num;
if(f)t[f].son[tim>t[f].tim]=x;
t[x].tim=tim;t[x].val=t[x].cnt=val;t[x].col=col;t[x].fa=f;t[x].size=1;
splay(x);
}
inline void change(int tim){
int x=root;
while(x&&t[x].tim!=tim)x=t[x].son[tim>t[x].tim];
if(x)t[x].val=0;splay(x);
}
inline int find(int tim,int col){
if(!mp[col]){
mp[col]=tim;
return 1;
}
else if(mp[col]>tim){
change(mp[col]);
mp[col]=tim;
return 1;
}
else return 0;
}
inline int findx(int x,int lim){
if(!x)return 0;
if(t[t[x].son[0]].size>=lim)findx(t[x].son[0],lim);
else if(t[t[x].son[0]].size+1>=lim)return t[t[x].son[0]].cnt+t[x].val+ans1;
else ans1+=t[t[x].son[0]].cnt+t[x].val,findx(t[x].son[1],lim-t[t[x].son[0]].size-1);
}
inline int findval(int lim){
ans1=0;
if(!lim)return 0;
if(lim>=t[root].size)return t[root].cnt;
return findx(root,lim);
}
}a[N];
inline void make(int x){
if(!x)return;
make(t[x].son[0]);
a[now].insert(t[x].tim,t[x].col,a[now].find(t[x].tim,t[x].col));
make(t[x].son[1]);
}int ans[N],k[N];
inline void dfs(int x,int fa){
for(register int i=head[x],j;i;i=e[i].next){
j=e[i].to;if(j==fa)continue;
dfs(j,x);
if(a[rec[x]].siz()<a[rec[j]].siz()){
now=rec[j];
make(a[rec[x]].root);
rec[x]=now;
}
else{
now=rec[x];
make(a[rec[j]].root);
}
}
ans[x]=a[rec[x]].findval(k[x]);
}
inline short main(){
freopen("ac7.in","r",stdin);
freopen("my.out","w",stdout);
n=read();
F(i,1,n-1){
int x=read(),y=read();add(x,y);add(y,x);
}
F(i,1,n)k[i]=read(),rec[i]=i;
m=read();
F(i,1,m){
int x=read(),y=read();
a[rec[x]].insert(i,y,a[rec[x]].find(i,y));
}
dfs(1,0);
q=read();
while(q--){
int x=read();
printf("%d\n",ans[x]);
}
return 0;
}
}
signed main() { return EMT::main();}

noip模拟6(T2更新的更多相关文章

  1. NOIP 模拟4 T2

    本题属于二和一问题 子问题相互对称 考虑对于问题一:知a求b 那么根据b数组定义式 显然能发现问题在于如何求dis(最短路) 有很多算法可供选择 dijsktra,floyed,bfs/dfs,spf ...

  2. 20161003 NOIP 模拟赛 T2 解题报告

    Weed duyege的电脑上面已经长草了,经过辨认上面有金坷垃的痕迹. 为了查出真相,duyege 准备修好电脑之后再进行一次金坷垃的模拟实验. 电脑上面有若干层金坷垃,每次只能在上面撒上一层高度为 ...

  3. 【2019.8.20 NOIP模拟赛 T2】小B的树(tree)(树形DP)

    树形\(DP\) 考虑设\(f_{i,j,k}\)表示在\(i\)的子树内,从\(i\)向下的最长链长度为\(j\),\(i\)子树内直径长度为\(k\)的概率. 然后我们就能发现这个东西直接转移是几 ...

  4. 【2019.7.15 NOIP模拟赛 T2】与非树(nand)(树形DP)

    树形\(DP\) 实际上,这道题应该不是很难. 我们设\(f_{x,i,j}\)表示在以\(x\)为根的子树内,原本应输出\(i\),结果输出了\(j\)的情况数. 转移时,为了方便,我们先考虑与,再 ...

  5. 20161023 NOIP 模拟赛 T2 解题报告

    Task 2.回文串计数 (calc.pas/calc.c/calc.cpp) [题目描述] 虽然是一名理科生,Mcx常常声称自己是一名真正的文科生.不知为何,他对于背诵总有一种莫名的热爱,这也促使他 ...

  6. 20161005 NOIP 模拟赛 T2 解题报告

    beautiful 2.1 题目描述 一个长度为 n 的序列,对于每个位置 i 的数 ai 都有一个优美值,其定义是:找到序列中最 长的一段 [l, r],满足 l ≤ i ≤ r,且 [l, r] ...

  7. 神奇的NOIP模拟赛 T2 LGTB 学分块

    LGTB 学分块 LGTB 最近在学分块,但是他太菜了,分的块数量太多他就混乱了,所以只能分成3 块今天他得到了一个数组,他突然也想把它分块,他想知道,把这个数组分成3 块,块可以为空.假设3 块各自 ...

  8. 2018.02.12 noip模拟赛T2

    二兵的赌注 Description游戏中,二兵要进入了一家奇怪的赌场.赌场中有n个庄家,每个庄家都可以猜大猜小,猜一次一元钱.每一次开彩前,你都可以到任意个庄家那里下赌注.如果开彩结果是大,你就可以得 ...

  9. ztz11的noip模拟赛T2:查房

    链接: https://www.luogu.org/problemnew/show/U46611 思路: 这道题告你n-1条边就是骗你的 部分分也是骗你的 这道题连对边5分钟的事 一个点对另一个点有影 ...

随机推荐

  1. 《Do Neural Dialog Systems Use the Conversation History Effectively? An Empirical Study》

    https://zhuanlan.zhihu.com/p/73723782 请复制粘贴到markdown 查看器查看! Do Neural Dialog Systems Use the Convers ...

  2. gitlab配置邮箱服务

    目录 1. SMTP服务 2. 服务端配置 3. 更新配置 4. 邮件测试 当需要进行 账号注册,创建项目,或合并分支等操作时,可通过邮件通知.邮件验证的方式实现. 1. SMTP服务 用于配置在服务 ...

  3. JSP核心技术

    一.JSP基本概念 JSP是Java Server Page 的简称,跟Servlet 一样可以动态生成HTML响应,文件命名为XXX.jsp JSP 与Servlet 的区别: jsp经编译后就变成 ...

  4. LeetCode解题记录(贪心算法)(二)

    1. 前言 由于后面还有很多题型要写,贪心算法目前可能就到此为止了,上一篇博客的地址为 LeetCode解题记录(贪心算法)(一) 下面正式开始我们的刷题之旅 2. 贪心 763. 划分字母区间(中等 ...

  5. 【LeetCode】59.螺旋矩阵II

    59.螺旋矩阵II 知识点:数组: 题目描述 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix . 示例 输入:n = 3 ...

  6. Redux-基本概念

    相关文档 1)         英文文档: https://redux.js.org/ 2)         中文文档: http://www.redux.org.cn/ 3)         Git ...

  7. windows下搭建vue开发环境实践

    Vue.js是一套构建用户界面的 "渐进式框架".与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计.Vue 的核心库只关注视图层,并且非常容易学习,非常容易与其它库或已 ...

  8. 导出数据在exlcel上

    1.前台写一个按钮跳到控制层 <a href="account.do?flag=out" >导出表格</a> 2.控制层导出数据方法 @RequestMap ...

  9. C++派生类的拷贝构造

    一. 概述 通过几个简单的实验,回顾下派生类中拷贝构造的相关知识. 环境:Centos7 64位, g++ 4.8.5 在继承中,构造器与析构器均没有被继承下来.拷贝构造,也是一种构造,也没有被继承下 ...

  10. Intouch 关于报表数据的一种思路

    在熟悉Intouch项目有一段时间了,也做有相关的三个项目,关于Intouch的一些报表数据的采集,也有了自己一定的看法(主要还是因为自己是野路子)今天就把我常用的一种制作思路,提供给大家.(仅供参考 ...