第一次打wannafly。。觉得自己好菜啊。。。

题目描述

在三维空间中,平面 x = 0, y = 0, z = 0,以及平面 x + y + z = K 围成了一个三棱锥。
整天与整数打交道的小明希望知道这个三棱锥内、上整点的数目。
他觉得数量可能很多,所以答案需要对给定的 M 取模。

输入描述:

输入有 1 ≤ T ≤ 10

5

 组数据。
每组数据中,输入两个整数 0 ≤ K ≤ 10

9

 + 7, 1 ≤ M ≤ 10

9

 + 7,意义如题目描述。

输出描述:

对于每组数据,输出一个整数,为三棱锥内、上整点的数目对 M 取模。

输入例子:
4
0 60
1 60
29 60
29 100007
输出例子:
1
4
40
4960

-->

示例1

输入

4
0 60
1 60
29 60
29 100007

输出

1
4
40
4960

签到题吧。对于这个三棱锥,除了x=0,y=0,z=0外的斜平面上,他有(k+1)列,由上往下数第i列包含i个点,于是我们斜平面上有点  $ sum^{k+1}_{i=1} \ i= \frac{(k+1)(k+2)}{2} $ 。因此给三棱锥等距地切出k个和斜平面平行的平面,因此三棱锥上的所有点分布在这(k+1)个平面上,于是从下往上数第i个平面上的点数为 $ \frac{(i)(i+1)}{2} $ 对其求和,即$ \sum^{k+1}_{i=1} \  \frac{(i)(i+1)}{2} = \frac{ \sum^{k+1}_{i=1} \ (i)(i+1)}{2} = \frac{ (k+1)(k+2)(k+3) }{6}  $ 因此按照公式写答案2333.

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e5+;
int T;
LL ans,k,m,dt,a[];
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
cin>>k>>m;
ans=;
for(int i=;i<=;i++)
a[i]=k+i;
for(int i=;i<=;i++)
if(a[i]%==)
{
a[i]/=;
break;
}
for(int i=;i<=;i++)
if(a[i]%==)
{
a[i]/=;
break;
}
ans=a[]*a[]%m*a[]%m;
cout<<ans<<endl;
}
}

题目描述

在一个 Minecraft 村庄中,村长有这一本小写字母构成的名册(字符串的表),
每个名字旁边都记录着这位村民的声望值,而且有的村民还和别人同名。
随着时间的推移,因为没有村民死亡,这个名册变得十分大。

现在需要您来帮忙维护这个名册,支持下列 4 种操作:
1. 插入新人名 si,声望为 ai
2. 给定名字前缀 pi 的所有人的声望值变化 di
3. 查询名字为 sj 村民们的声望值的和(因为会有重名的)
4. 查询名字前缀为 pj 的声望值的和

输入描述:

第一行为两个整数 0 ≤ N ≤ 10

5

,表示接下来有 N 个操作;
接下来 N 行,每行输入一个操作,行首为一个整数 1 ≤ o

i

 ≤ 4,表示这一行的操作的种类,
那么这一行的操作和格式为:
1. 插入人名,这一行的格式为 1 si ai,其中 |ai| ≤ 103
2. 前缀修改声望,这一行的格式为 2 pi di,其中 |di| ≤ 103
3. 查询名字的声望和,这一行的格式为 3 sj
4. 查询前缀的声望和,这一行的格式为 4 pj
输入保证插入人名的字符串的长度和小于或等于 105,总的字符串的长度和小于或等于 106

输出描述:

对于每一次询问操作,在一行里面输出答案。

输入例子:
20
1 a -10
1 abcba -9
1 abcbacd 5
4 a
2 a 9
3 aadaa
3 abcbacd
4 a
3 a
2 a 10
3 a
2 a -2
2 d -8
1 ab -2
2 ab -7
1 aadaa -3
4 a
3 abcba
4 a
4 c
输出例子:
-14
0
14
13
-1
9
11
1
11
0

-->

示例1

输入

20
1 a -10
1 abcba -9
1 abcbacd 5
4 a
2 a 9
3 aadaa
3 abcbacd
4 a
3 a
2 a 10
3 a
2 a -2
2 d -8
1 ab -2
2 ab -7
1 aadaa -3
4 a
3 abcba
4 a
4 c

输出

-14
0
14
13
-1
9
11
1
11
0
 
 

给trie做类似线段树的tag标记。
我们维护五个量,分别是当前节点路径字符串的数量、声望和,当前节点为前缀字符串的数量、声望和,以及标记tag。对于所有操作,操作的时候访问到当前点有tag的时候就往后面的节点pushdown。操作一在插入基础上pushdown。操作二像线段树一样,如果当前前缀存在,我们修改路径上的所有节点的值,并在终点处留下加上声望值的tag。三四操作就在pushdown后查询当前点的前缀声望和和前缀声望和。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=1e6+;
const int type=;
int T;
struct node
{
int next[type];
LL tag,sum,num,presum,prenum;
}trie[N];
int tot;
char s[N];
int n,m;
LL d;
void init()
{
tot=;
memset(&trie[],,sizeof(trie[]));
return ;
}
int makenode()
{
++tot;
memset(&trie[tot],,sizeof(trie[tot]));
return tot;
}
void pushdown(int now)
{
int p;
if(trie[now].tag)
{
for(int i=;i<type;i++)
{
p=trie[now].next[i];
if(p)
{
trie[p].tag+=trie[now].tag;
trie[p].sum+=trie[p].num*trie[now].tag;
trie[p].presum+=trie[p].prenum*trie[now].tag;
}
}
trie[now].tag=;
}
return ;
}
void add(char *s,LL d)
{
int now=,p;
for(int i=;s[i];i++)
{
p=s[i]-'a';
if(!trie[now].next[p])
trie[now].next[p]=makenode();
now=trie[now].next[p];
pushdown(now);
trie[now].presum+=d;
trie[now].prenum++;
}
trie[now].sum+=d;
trie[now].num++;
return ;
}
void change(char *s,LL d)
{
int now=,p;
int i;
for(i=;s[i];i++)
{
p=s[i]-'a';
if(!trie[now].next[p])
break;
now=trie[now].next[p];
pushdown(now);
}
if(!s[i])
{
trie[now].tag+=d;
int nowto=;
for(i=;s[i];i++)
{
p=s[i]-'a';
nowto=trie[nowto].next[p];
trie[nowto].presum+=trie[now].prenum*d;
}
trie[now].sum+=d*trie[now].num;
}
return ;
}
LL query(char *s)
{
int now=,p;
int i;
for(i=;s[i];i++)
{
p=s[i]-'a';
if(!trie[now].next[p])
break;
now=trie[now].next[p];
pushdown(now);
}
if(s[i])
return ;
else
return trie[now].sum;
}
LL querypre(char *s)
{
int now=,p;
int i;
for(i=;s[i];i++)
{
p=s[i]-'a';
if(!trie[now].next[p])
break;
now=trie[now].next[p];
pushdown(now);
}
if(s[i])
return ;
else
return trie[now].presum;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
init();
for(int i=;i<=n;i++)
{
cin>>m;
if(m==)
{
cin>>s>>d;
add(s,d);
}
else if(m==)
{
cin>>s>>d;
change(s,d);
}
else if(m==)
{
cin>>s;
cout<<query(s)<<endl;
}
else
{
cin>>s;
cout<<querypre(s)<<endl;
}
}
return ;
}

题目描述

codeJan有一天脑洞大开,想到一个有趣的问题。给一个固定根为1号结点的树,定义一个子树的beauty是这个子树的根节点到所有这棵树上其他节点的距离和,叶子节点的beauty是0。定义一个子树的sub-beauty是这个子树的beauty值减去这个子树的某一个子树(不包括自身)的beauty值。显然一个子树的beauty值是唯一的,而sub-beauty值可以有很多个。codeJan想要知道所有子树的所有sub-beauty中不超过m的最大值。

输入描述:

第一行是一个T≤20代表测试组数。每组测试的第一行包含两个正整数是n,m(n≤10

5

,m≤10

8

),接下来n−1
行每行包含三个正整数a b d,分别表示a结点和b结点之间的距离是d,a,b∈[1,n],1≤d≤10

3

。请注意每棵树的根节点都是1号结点,并且保证输入合法。

输出描述:

对于每组测试样例输出一个整数表示所有子树sub-beauty中不超过m的最大值。如果所有子树的sub-beauty都大于m,输出-1。

输入例子:
3
3 4
1 2 1
1 3 2
3 4
1 2 3
1 3 2
4 6
1 2 2
2 3 5
3 4 2
输出例子:
3
-1
6

-->

示例1

输入

3
3 4
1 2 1
1 3 2
3 4
1 2 3
1 3 2
4 6
1 2 2
2 3 5
3 4 2

输出

3
-1
6

我们一次dfs求出所有点的beauty,然后我们第二次dfs,并保存根到当前点的路径上的点的beauty。由于这个beauty是非递增的,因此我们直接查询大于等于当前点u的sum[u] m的值在路径bueauty的位置,然后+1即为相减后最靠近m的值了。由于我傻了没发现递增。。于是我写了一个权值线段树维护orz。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=1e5+;
vector<pair<int,LL>> edge[N];
LL sum[N],cnum[N],val[N];
int n,T,u,v,nl;
LL m,value,ans;
struct node
{
int l,r,num;
}tree[N<<];
void init(int i,int l,int r)
{
tree[i]=(node){l,r};
if(l==r)
return ;
int mid=(l+r)>>;
init(i<<,l,mid);
init(i<<|,mid+,r);
return ;
}
void update(int i,int pos,int val)
{
if(tree[i].l==tree[i].r)
{
tree[i].num+=val;
return ;
}
int mid=(tree[i].l+tree[i].r)>>;
if(mid>=pos)
update(i<<,pos,val);
else
update(i<<|,pos,val);
tree[i].num+=val;
return ;
}
LL query(int i,int l,int r)
{
if(tree[i].num==)
return -INF;
if(tree[i].l>=l && tree[i].r<=r)
{
if(tree[i].l==tree[i].r)
return val[tree[i].l];
if(tree[i<<|].num)
return query(i<<|,l,r);
else return query(i<<,l,r);
}
int mid=(tree[i].l+tree[i].r)>>;
LL ans=-INF;
if(mid>=l)
ans=max(ans,query(i<<,l,r));
if(mid<r)
ans=max(ans,query(i<<|,l,r));
return ans;
}
void dfs1(int u,int f)
{
cnum[u]=;
sum[u]=;
for(auto p:edge[u])
{
if(p.first!=f)
{
dfs1(p.first,u);
cnum[u]+=cnum[p.first];
sum[u]+=cnum[p.first]*p.second+sum[p.first];
}
}
val[u]=sum[u];
return ;
}
void dfs2(int u,int f)
{
ans=max(query(,lower_bound(val+,val+nl+,sum[u])-val,upper_bound(val+,val+nl+,sum[u]+m)--val)-sum[u],ans);
update(,lower_bound(val+,val+nl+,sum[u])-val,);
for(auto p:edge[u])
if(p.first!=f)
dfs2(p.first,u);
update(,lower_bound(val+,val+nl+,sum[u])-val,-);
return ;
}
int main()
{
ios::sync_with_stdio(false);
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=;i<=n;i++)
edge[i].clear();
for(int i=;i<=n;i++)
{
cin>>u>>v>>value;
edge[u].pb(mp(v,value));
edge[v].pb(mp(u,value));
}
ans=-;
dfs1(,);
sort(val+,val+n+);
nl=unique(val+,val+n+)-val-;
init(,,nl);
dfs2(,);
cout<<ans<<endl;
}
return ;
}

题目描述

给一个1-base数组{a},有N次操作,每次操作会使一个位置无效。一个区间的权值定义为这个区间里选出一些数的异或和的最大值。求在每次操作前,所有不包含无效位置的区间的权值的最大值。

输入描述:

第一行读入一个正整数(1 <= n <= 105)

第二行读入n个正整数,第i个表示a[i](0<= a[i] <= 109)

第三行读入n个正整数,第i个表示x[i]即第i次操作的位置,保证x[i]互不相同。

输出描述:

输出n行答案

输入例子:
10
169 816 709 896 58 490 97 254 99 796
4 2 3 10 5 6 1 8 9 7
输出例子:
1023
994
994
994
490
490
254
254
99
97

-->

示例1

输入

10
169 816 709 896 58 490 97 254 99 796
4 2 3 10 5 6 1 8 9 7

输出

1023
994
994
994
490
490
254
254
99
97

明显这个是分割区间的题,那么对于这种题我们就应该反着做,变成合并区间。求一个集合里任选的亦或最大值,那么首选就是线性基啦。那么从后往前做的话就相当于每次合并无效位置点和他左侧点所在区间(如果有的话)以及他右侧点所在区间(如果有的话)的线性基。我们可以用并查集来记录他们丛属哪个区间,以及区间的线性基。并拿这个合并后的线性基求最大值来更新当前亦或最大值。
 
 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define mod 1000000007
#define LL long long
#define INF 0x3f3f3f3f
#define pb(x) push_back(x)
#define mp(x,y) make_pair(x,y)
using namespace std;
const int N=1e5+;
const int type=;
int fa[N];
int Find(int x)
{
if(fa[x]!=x)
fa[x]=Find(fa[x]);
return fa[x];
}
LL liner[N][type],ans[N],rans,p;
int n,a[N],x[N],vis[N];
int t;
void Union(int x,int y)
{
int xx=Find(x);
int yy=Find(y);
LL p;
for(int i=type-;i>=;i--)
{
if(liner[xx][i])
{
p=liner[xx][i];
for(int j=type-;j>=;j--)
{
if(p>>j)
{
if(liner[yy][j])
p^=liner[yy][j];
else
{
liner[yy][j]=p;
break;
}
}
}
}
}
fa[xx]=yy;
return ;
}
void init(int n)
{
clr(liner);
LL p;
for(int i=;i<=n;i++)
{
fa[i]=i;
vis[i]=;
p=(LL)a[i];
for(int j=type-;j>=;j--)
{
if(p>>j)
{
if(!liner[i][j])
{
liner[i][j]=p;
break;
}
else
p=p^liner[i][j];
}
}
}
return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",a+i);
for(int i=;i<=n;i++)
scanf("%d",x+i);
init(n);
rans=;
for(int i=n;i>=;i--)
{
vis[x[i]]=;
if(vis[x[i]-])
Union(x[i]-,x[i]);
if(vis[x[i]+])
Union(x[i]+,x[i]);
t=Find(x[i]);
p=;
for(int j=;j>=;j--)
if(liner[t][j])
p=max(p^liner[t][j],p);
rans=max(rans,p);
ans[i]=rans;
}
for(int i=;i<=n;i++)
printf("%lld\n",ans[i]);
return ;
}

wannafly挑战赛14的更多相关文章

  1. 牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树)

    牛客wannafly 挑战赛14 B 前缀查询(trie树上dfs序+线段树) 链接:https://ac.nowcoder.com/acm/problem/15706 现在需要您来帮忙维护这个名册, ...

  2. Wannafly挑战赛14 C.可达性(tarjan缩点)

    题目描述 给出一个 0 ≤ N ≤ 105 点数.0 ≤ M ≤ 105 边数的有向图, 输出一个尽可能小的点集,使得从这些点出发能够到达任意一点,如果有多个这样的集合,输出这些集合升序排序后字典序最 ...

  3. Wannafly挑战赛14 - E 并查集维护线性基区间

    给一个1-base数组{a},有N次操作,每次操作会使一个位置无效.一个区间的权值定义为这个区间里选出一些数的异或和的最大值.求在每次操作前,所有不包含无效位置的区间的权值的最大值. 线性基删除不知道 ...

  4. Wannafly挑战赛27

    Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...

  5. Wannafly挑战赛25游记

    Wannafly挑战赛25游记 A - 因子 题目大意: 令\(x=n!(n\le10^{12})\),给定一大于\(1\)的正整数\(p(p\le10000)\)求一个\(k\)使得\(p^k|x\ ...

  6. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  7. Wannafly挑战赛21A

    题目链接 Wannafly挑战赛21A 题解 代码 #include <cstdio> #include <cmath> #define MAX 1000005 #define ...

  8. Wannafly挑战赛24游记

    Wannafly挑战赛24游记 A - 石子游戏 题目大意: A和B两人玩游戏,总共有\(n(n\le10^4)\)堆石子,轮流进行一些操作,不能进行下去的人则输掉这局游戏.操作包含以下两种: 把石子 ...

  9. Wannafly挑战赛25C 期望操作数

    Wannafly挑战赛25C 期望操作数 简单题啦 \(f[i]=\frac{\sum_{j<=i}f[j]}{i}+1\) \(f[i]=\frac{f[i]}{i}+\frac{\sum_{ ...

随机推荐

  1. UIToolBar的半透明属性设置

      UIToolBar的半透明属性设置style:Translucent(Ps:长得很像翻译translation)   https://www.evernote.com/shard/s227/sh/ ...

  2. Http跨域时候预检没通过的几种原因

    网上大多数涉及的原因(直接复制粘帖): CORS把HTTP请求分成两类,不同类别按不同的策略进行跨域资源共享协商. 1. 简单跨域请求. 当HTTP请求出现以下两种情况时,浏览器认为是简单跨域请求: ...

  3. centos6.4 yum安装nginx+mysql+php

    1.配置防火墙,开启80端口.3306端口vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport ...

  4. HDU 1159 Common Subsequence (dp)

    题目链接 Problem Description A subsequence of a given sequence is the given sequence with some elements ...

  5. vue数组操作不触发前端重新渲染

    暂时使用给数组先赋值 [ ] ,然后重新赋值的方式解决. 此外,能够监听的数组变异方法 https://cn.vuejs.org/v2/guide/list.html#%E5%8F%98%E5%BC% ...

  6. 【DeepLearning学习笔记】Coursera课程《Neural Networks and Deep Learning》——Week2 Neural Networks Basics课堂笔记

    Coursera课程<Neural Networks and Deep Learning> deeplearning.ai Week2 Neural Networks Basics 2.1 ...

  7. Linux的SMP,UMA,NUMA

    SMP 是Symmetric Multi-Processing的意思,对称多处理器,一种多核结构,认为这些核是完全同构的,任务可以随便在任一个核上跑. UMA是Uniform Memory Acces ...

  8. swift中的如果在构造方法中使用KVC, 调用了super.init(), 报错, 基本数据类型属性找不到

    swift要求, 属性必须有初始化值, 如果不对其赋值, 可以加一个?系统会默认给其包装一个可选值(直说就是nil) 如果定义一个基本类型, 建议直接赋值, 不建议使用? 下面说下标题中的问题 有时候 ...

  9. FineReport——JS二次开发(局部刷新)

    在FR中,可以通过在form表单设置多个报表模板,然后通过对某一模板刷新实现局部刷新的功能,在cpt模板中,由于只存在一个模板,所以无法实现局部刷新. 其实,最好的局部刷新办法是自定义一个页面,然后添 ...

  10. EXT入门学习

    今天,对EXT做了一下初步的了解,了解了一些基本用的函数.窗体对象.表单.文本域.按钮,一些基本的函数我列了出来,写了个登陆的demo,是根据别人的例子模仿出来的,见谅哈. 基本函数 Ext.onRe ...