由于蒟弱目前还没调出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. kong插件Prometheus+grafana图形化展示

    目录 1. 准备工作 3. 为kong添加 prometheus插件 4. 打开kong的metrics支持 4. 配置prometheus.yml添加kong提供的数据信息 5. 在 Grafana ...

  2. 第一个用户进程 - Android 的 Init 进程

    本文尝试对着 <深入理解 Android 5.0 系统>来对 android 9.0 的启动代码进行分析,但是分析过程中发现自己缺乏操作系统方面的知识,以致于只能做一些简单分析.最近也买了 ...

  3. [TJOI2007]书架 题解

    文中给了你一些句子,以及让你任意插入某个位置以及查询某个位置的句子. 发现因为是句子很难搞,所以开个 map 离散一下成数字.然后在额外开一个 map 记录这个数字对应的句子. 然后你要写一种支持插入 ...

  4. 华为:harmonyos 鸿蒙

    鸿蒙 1.设置--更新 2.华为搜索--抢鲜体验-下载描述文件--同意 3.更新-安装

  5. VBA:考场场标打印

    Function pda(x) a = x If Len(a) = 1 Then ab = "00" & a ElseIf Len(a) = 2 Then ab = &qu ...

  6. 使用 VSCode 搭建 Flutter环境

    概述 编辑器使用 vscode,不再安装 Android Studio. 安装 Git 点击这里 下载并安装 Git 配置 Java 环境 下载和安装 JDK 点击下载 Java SE Develop ...

  7. [刘阳Java]_酷炫视频播放器制作_JS篇

    此文章是接着上次写的<酷炫视频播放器制作_界面篇>将其完善,我们主要给大家介绍一下如何利用JS脚本来控制视频的播放.为了让大家能够保持对要完成的功能有直接的了解,我们还是将效果图附到文章里 ...

  8. Requests方法 -- Blog流程类进行关联

    1.接口封装关联 1.有些接口经常会用到比如登录的接口,这时候我们可以每个接口都封装成一个方法,如:登录.保存草稿.发帖.删帖,这四个接口就可以写成四个方法2.接口封装好了后,后面我们写用例那就直接调 ...

  9. python 连接远程服务器,修改时间

    import paramiko from datetime import date, timedelta def set_time(hostname): ssh = paramiko.SSHClien ...

  10. 高德开放平台实现批量自定义marker和信息窗体显示

    上篇博客提到云图无法实现文本标签标记marker,这篇博客着重实现在marker点文本标记以及自定义按钮窗体显示. 1.效果: 2.代码实现 <!doctype html> <htm ...