T1 动态逆序对

题目

【题目描述】

给出一个长度为n的排列a(1~n这n个数在数列中各出现1次)。每次交换两个数,求逆序对数%2的结果。

逆序对:对于两个数a[i],a[j](i<j),若a[i]>a[j],则(a[i],a[j])为1个逆序对。

【输入格式】

第一行一个正整数n。

接下来一行n个数,表示给出的排列a。

接下来一行一个正整数q。

接下来q行,每行两个正整数i,j,表示交换a[i]和a[j]。

【输出格式】

输出共q行,表示每次交换后的逆序对数%2的结果。

【输入样例】


【输出样例】


【数据规模】

对于60%的数据:n,q≤100;

对于80%的数据:n,q≤1000;

对于100%的数据:n,q≤100000。

解析

先求出初始序列的逆序对总数对2取余的结果。

每次交换a[i]与a[j](i<j),对于a[k]的影响如下:

  • 若k<i,a[k]依旧在a[i]与a[j]前面,所以a[k]与a[i]、a[j]产生的逆序对数不变;
  • 若k>j,同上,逆序对数不变;
  • 若i<k<j,如果a[i]<a[k],则逆序对数+1,否则-1,;如果a[j]>a[k],则逆序对数+1,否则-1,

而我们只需求出逆序对数对2取余的结果,可以发现,逆序对个数的奇偶性与k无关。

事实上,只需在每次交换位置时,令逆序对总数对2取余的结果^1即可(i=j时则不变)。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
inline int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,q,a[],f[],temp;
void add(int x,int y)
{
for(;x<=n;x+=(x&-x)) f[x]+=y;
}
int ask(int x)
{
int ans=;
for(;x;x-=(x&-x)) ans+=f[x];
return ans;
}
int main()
{
//freopen("lyk.in","r",stdin);
//freopen("lyk.out","w",stdout);
n=read();
for(int i=;i<=n;i++) a[i]=read();
q=read();
for(int i=n;i>=;i--)
{
temp+=ask(a[i]-);
add(a[i],);
}
temp&=;
for(int i=;i<=q;i++)
{
int x=read(),y=read();
if(x!=y) temp^=;
cout<<temp<<endl;
}
return ;
}

T2 树的统计

题目

【题目描述】

给出一棵n个点的满二叉树,根节点为1,第i个点的左右子节点分别为第2i,2i+1个点,第i个点的权值为a[i]。

有m个询问。对于每个询问给出x,d,求到点x的距离为d的所有点的点权和。如果不存在符合条件的点,输出0。

两点距离即两点间最短路径的边数。

保证最终答案在int范围内。

【输入格式】

第一行两个正整数n,m。

接下来n行每行一个正整数,第i行的数表示a[i]。

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

【输出格式】

对于每个询问输出一行表示答案。

【输入样例】


【输出样例】


【数据规模】

对于80%的数据,n≤1023,m≤1000。

对于100%的数据,n≤131071,m≤100000,n=2t-1,1≤t≤17,a[i]≤30000。

解析

对于每个询问,用dfs搜索与点x距离为d的点,进行统计即可。

注意每个点之间的关系,访问父亲是x<<1,左儿子是x>>1,右儿子是x>>1+1,要特判一下左右儿子编号不能大于n,否则会RE。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
inline int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
const int N=;
int n,m,a[N],dd,ans;
void dfs(int x,int d,int from)
{
if(d>dd) return ;
if(d==dd)
{
ans+=a[x];
return ;
}
int y=x>>;
if(y>=&&y!=from) dfs(y,d+,x);
y=x<<;
if(y<=n&&y!=from) dfs(y,d+,x);
if(y+<=n&&y+!=from) dfs(y+,d+,x);
}
int main()
{
//freopen("dream.in","r",stdin);
//freopen("dream.out","w",stdout);
n=read(),m=read();
a[]=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=m;i++)
{
int x=read();
dd=read(),ans=;
dfs(x,,);
cout<<ans<<endl;
}
return ;
}

T3 宣传栏

题目

【题目描述】

有一个大型的矩形宣传栏,高和宽分别为h和m。宣传栏是用来张贴告示的地方,最初,宣传栏是空的,但此后告示将一张一张的被放上去。

有n张告示,每张告示的高都是一个单位长度,第i张贴上的告示宽度为w[i]。

每次张贴时,总是将告示贴在可以张贴且最高的地方,如果有多个可行的地方,则选择最左边张贴。

给定宣传栏的高和宽,你的任务是找出每个告示张贴在第几行。

【输入格式】

第一行为三个整数,h,m和n(1≤m≤109;1≤h≤n≤200000),表示宣传栏的尺寸和张贴的告示个数。

接下来n行表示w[i](1≤w[i]≤109)。

【输出格式】

每行一个整数表示答案。如果第i个告示没地方贴,输出-1。

【输入样例】


【输出样例】


-

【数据规模】

对于20%的数据,n=1。

对于40%的数据,n,m≤500。

对于70%的数据,n≤2000。

对于90%的数据,n≤50000。

对于100%的数据,n≤200000。

解析

用c[i]表示第i行还剩多少长度。

用线段树维护c[i]的区间最大值即可。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
inline int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int h,m,n,c[];
int w;
void build(int p,int l,int r)
{
c[p]=m;
if(l==r) return ;
int mid=(l+r)>>;
build(p*,l,mid),build(p*+,mid+,r);
}
int ask(int p,int l,int r)
{
if(l==r)
{
c[p]-=w;
return l;
}
int mid=(l+r)>>;
if(c[p*]>=w)
{
int temp=ask(p*,l,mid);
c[p]=max(c[p*+],c[p*]);
return temp;
}
else
{
int temp=ask(p*+,mid+,r);
c[p]=max(c[p*+],c[p*]);
return temp;
}
}
int main()
{
//freopen("billboard.in","r",stdin);
//freopen("billboard.out","w",stdout);
h=read(),m=read(),n=read();
build(,,h);
for(int i=;i<=n;i++)
{
w=read();
if(w>c[])
{
cout<<"-1"<<endl;
continue;
}
cout<<ask(,,h)<<endl;
}
return ;
}

T4 种树

题目

【题目描述】

你要在一条无穷长的马路上种树。

你想种3种树,分别是草莓树,西瓜树,土豆树。

给定3个正整数A,B,C,你可以选择3个整数x,y,z,然后:

  • 在位置 … , x-2A , x-A , x , x+A , x+2A , … 分别种1棵草莓树。
  • 在位置 … , y-2B , y-B , y , y+B , y+2B , … 分别种1棵西瓜树。
  • 在位置 … , z-2C ,z-C , z , z+C , z+2C , … 分别种1棵土豆树。

你想要最大化最近的两棵树的距离,请你输出这个最大距离。

【输入格式】

每个测试点多组测试数据。

每组数据输入一行A,B,C。

没给出数据组数,你可以这样输入:

while (scanf(“%d%d%d”, &A, &B, &C) == 3)

{

……

}

【输出格式】

对于每个询问输出一行表示答案。

【输入样例】


【输出样例】


【数据规模】

对于100%的数据,1≤A,B,C≤2000。

解析

先用solve函数求出三树两两之间最小距离的最小值,然后再找到最大的即可。

证明过程比较麻烦,本蒟蒻数论不太好,就不给出详细证明了。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
using namespace std;
int a,b,c,x,y,z,ans;
int gcd(int x,int y)
{
if(y==) return x;
return gcd(y,x%y);
}
int solve(int a,int b,int x,int y)
{
int g=gcd(a,b);
int t=(x-y)%g;
if(t<) t+=g;
return min(t,g-t);
}
int main()
{
while(cin>>a>>b>>c)
{
ans=;
for(y=;y<b;y++)
for(z=;z<c;z++)
{
int temp;
temp=min(solve(a,b,,y),min(solve(b,c,y,z),solve(a,c,,z)));
ans=max(ans,temp);
}
cout<<ans<<endl;
}
return ;
}

长乐国庆集训Day3的更多相关文章

  1. 长乐国庆集训Day5

    T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...

  2. 长乐国庆集训Day5-2

    T1 彩虹 题目 [题目描述] Mr.Raju和他的一个大家庭外出度假,他们想要乘着彩虹欣赏周围的景色,但是这样最会有一些问题. 在他们家族中,如果一个人想要骑上彩虹,那么他喜欢的所有人和喜欢他的所有 ...

  3. 长乐国庆集训Day4

    T1 一道数论神题 题目 [题目描述] LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图,只有点权. LYK想把这个图删干净,它的方法是这样的.每次选择一个点,将它删 ...

  4. 长乐国庆集训Day2

    T1 连珠风暴 题目 [题目描述] 给定M种颜色的珠子,每种颜色珠子的个数均不限,将这些珠子做成长度为N的项链. 问能做成多少种不重复的项链.两条项链相同,当且仅当两条项链通过旋转或是翻转后能重合在一 ...

  5. 长乐国庆集训Day1

    T1 统计数字 题目 [题目描述] 设 S(N ) 表示 N 的各位数字之和,如 S(484) = 4+8+4 = 16, S(22) = 2+2 = 4. 如果一个正整数满足 S(x*x) = S( ...

  6. 【LOJ6067】【2017 山东一轮集训 Day3】第三题 FFT

    [LOJ6067][2017 山东一轮集训 Day3]第三题 FFT 题目大意 给你 \(n,b,c,d,e,a_0,a_1,\ldots,a_{n-1}\),定义 \[ \begin{align} ...

  7. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

  8. 牛客国庆集训派对Day6 A Birthday 费用流

    牛客国庆集训派对Day6 A Birthday:https://www.nowcoder.com/acm/contest/206/A 题意: 恬恬的生日临近了.宇扬给她准备了一个蛋糕. 正如往常一样, ...

  9. 国庆集训 Day1 T2 生成图 DP

    国庆集训 Day1 T2 生成图 现在要生成一张\(n\)个点的有向图.要求满足: 1.若有 a->b的边,则有 b->a 的边 2.若有 a->b 的边和 b->c 的边,则 ...

随机推荐

  1. 单片机模块化程序: 单片机AT指令配置模块程序模板(非阻塞版)

    拷贝这两个文件到自己的工程 测试1://单片机发送AT+RST\r\n  如果单片机串口接收到OK 或者ready 执行下一条 测试视频: https://qqqqqbucket.oss-cn-bei ...

  2. 【JZOJ6233】【20190627】心的旋律

    题目 你需要构造一个\(n\)个点的二分图 定义\(F(A)\)表示左部点集\(A\)能够到达的右部中的点 使得满足 $ F(A) \lt |A| $ 的集合恰好有 $ k $ 个 \(1 \le n ...

  3. C语言中常见的图形打印总结

    直角三角形(靠右直立) 示例实现代码如下: int main(){ int n; int i,j; cin >> n; if(n<= 0){ cout << " ...

  4. STL中find和sort的用法总结

    STL算法 STL 提供能在各种容器中通用的算法(大约有70种),如插入.删除.查找.排序等. 许多算法操作的是容器上的一个区间(也可以是整个容器),因此需要两个参数,一个是区间起点元素的迭代器,另一 ...

  5. Linux 和 windows下查看运行命令的位置

    经常遇到要查看某个命令的运行文件在哪儿! 比如说vue cli,经常使用vue命令创建项目,如果你对nodejs的全局包安装目录了解可能一下就找到了, 蛋疼的是不一定每个命令都是nodejs下的,有可 ...

  6. OpenVSwitch实验参考

    1. 使用Floodlight管理OVS桥 (1) 下载:https://codeload.github.com/floodlight/floodlight/tar.gz/v1.2 (2) tar x ...

  7. bootstrap 多级联动下拉框

    <!DOCTYPE HTML> <html lang="zh-CN"> <head> <meta charset="UTF-8& ...

  8. 【POJ3278】Catch That Cow

    本题传送门 本题知识点:宽度优先搜索 题意很简单,我们把FJ与奶牛看作是在一条数轴上的点,奶牛固定在K点,FJ的移动有三种,分别是向前一格,向后一格以及跳到当前格的两倍去.问FJ花费最少的时间到达奶牛 ...

  9. 云服务器搭建JDK+Tomcat+MySQL环境

    一.首先租赁一台云服务器(阿里云服务器或者腾讯云服务器) 其实可以在windows电脑上使用VMware workstation来安装虚拟机进行操作,毕竟云服务器低配也是很贵的.不过可以使用学生价去租 ...

  10. Java String.split()函数分隔回车注意事项

    作者:Sun1956 原文:https://blog.csdn.net/sun1956/article/details/45096117 --------------------- 我们在Java中如 ...