Codeforces Round #376 (Div. 2) D. 80-th Level Archeology —— 差分法 + 线段扫描法
题目链接:http://codeforces.com/contest/731/problem/D
2 seconds
256 megabytes
standard input
standard output
Archeologists have found a secret pass in the dungeon of one of the pyramids of Cycleland. To enter the treasury they have to open an unusual lock on the door. The lock consists of n words,
each consisting of some hieroglyphs. The wall near the lock has a round switch. Each rotation of this switch changes the hieroglyphs according to some rules. The instruction nearby says that the door will open only if words written on the lock would be sorted
in lexicographical order (the definition of lexicographical comparison in given in notes section).
The rule that changes hieroglyphs is the following. One clockwise rotation of the round switch replaces each hieroglyph with the next hieroglyph in alphabet, i.e. hieroglyph x (1 ≤ x ≤ c - 1)
is replaced with hieroglyph (x + 1), and hieroglyph c is
replaced with hieroglyph 1.
Help archeologist determine, how many clockwise rotations they should perform in order to open the door, or determine that this is impossible, i.e. no cyclic shift of the alphabet will make the sequence of words sorted lexicographically.
The first line of the input contains two integers n and c (2 ≤ n ≤ 500 000, 1 ≤ c ≤ 106) —
the number of words, written on the lock, and the number of different hieroglyphs.
Each of the following n lines contains the description of one word. The i-th
of these lines starts with integer li (1 ≤ li ≤ 500 000),
that denotes the length of the i-th word, followed by li integers wi, 1, wi, 2,
..., wi, li (1 ≤ wi, j ≤ c) —
the indices of hieroglyphs that make up the i-th word. Hieroglyph with index 1 is
the smallest in the alphabet and with index c — the biggest.
It's guaranteed, that the total length of all words doesn't exceed 106.
If it is possible to open the door by rotating the round switch, print integer x (0 ≤ x ≤ c - 1)
that defines the required number of clockwise rotations. If there are several valid x, print any of them.
If it is impossible to open the door by this method, print - 1.
4 3
2 3 2
1 1
3 2 3 1
4 2 3 1 2
1
2 5
2 4 2
2 4 2
0
4 4
1 2
1 3
1 4
1 2
-1
Word a1, a2, ..., am of
length m is lexicographically not greater than word b1, b2, ..., bk of
length k, if one of two conditions hold:
- at first position i, such that ai ≠ bi,
the character ai goes
earlier in the alphabet than character bi,
i.e. a has smaller character in the first position where they differ; - if there is no such position i and m ≤ k,
i.e. the first word is a prefix of the second or two words are equal.
The sequence of words is said to be sorted in lexicographical order if each word (except the last one) is lexicographically not greater than the next word.
In the first sample, after the round switch is rotated 1 position clockwise the words look as follows:
1 3
2
3 1 2
3 1 2 3
In the second sample, words are already sorted in lexicographical order.
In the last sample, one can check that no shift of the alphabet will work.
题意:
给出n个单词(字母的取值范围为1~c),以及一种操作:将每个单词的每个字母+1(如果字母为c,则变为1)。
问:能否经过若干次操作后,这些单词以字典序排列?若能形成字典序,那么操作次数的范围为:0~c-1 , 因为操作c次后又变回原来的值;若不能形成字典序,则输出-1。
题解:
对于上下两个单词的第一次出现字母不相等的位置,为了使其形成升序,有相应的操作次数的区间。
然后每一对单词,都有相应的区间,最后答案就在所有区间的交集上取得(区间用差分法实现)。
线段扫描法:在差分法的基础上,求前缀和,当前缀和刚好等于n-1时(总共有n-1对单词),即表明此处满足每一对单词的取值。
学习之处:
1.选定了某一操作对象,如果很难下手,那么可以更换操作对象。
2.差分法 + 线段扫描法 求交集。
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-6;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 1e6+10; vector<int>v[maxn>>1];
int range[maxn];
int n,c; void init()
{
scanf("%d%d",&n,&c);
memset(range,0,sizeof(range));
for(int i = 1; i<=n; i++)
v[i].clear();
for(int i = 1; i<=n; i++)
{
int tot,x;
scanf("%d",&tot);
v[i].push_back(tot);
for(int j = 1; j<=tot; j++)
{
scanf("%d",&x);
v[i].push_back(x);
}
}
} void modify(int l, int r) //差分法
{
range[l]++;
range[r+1]--;
} int solve()
{
for(int i = 2; i<=n; i++)
{
int tot = min(v[i-1][0], v[i][0]);
int j = 1;
while(j<=tot && v[i-1][j]==v[i][j]) j++;
if(j>tot)
{
if(v[i][0]<v[i-1][0]) return -1;
else modify(0, c-1);
}
else
{
int x = v[i-1][j];
int y = v[i][j]; if(x<y) modify(0, c-y), modify(c-x+1, c-1);
else modify(c-x+1, c-y);
}
} int cnt = 0;
for(int i = 0; i<c; i++) //线段扫描法
{
cnt += range[i];
if(cnt==n-1) //(1,2)、(2,3)……(n-1,n),所以总数为n-1
return i;
}
return -1;
} int main()
{
init();
cout<< solve() <<endl;
}
以下是自家学校有关差分法的题目:
18100 奇怪的光照植物
该题有题解
时间限制:500MS 内存限制:65535K
提交次数:547 通过次数:64
题型: 编程题 语言: G++;GCC;VC
Description
一种光照植物,用光照射一天就长1厘米。现在将这种植物种在一条直线型的
培养容器中,坐标从0到n-1,每一个整点位置种植一棵这种植物,即共n棵。
开始的时候所有植物的高度都为0。实验过程中,进行了m组,每组选择对范围为
[L,R]的植物进行光照a天,每组参数L、R、a由输入数据给出。
当所有实验结束后,我们想知道所有光照了奇数天的植物总的高度是多少(单位:厘米)。
输入格式
输入第一行包含一个整数T(T<=10),表示有T组测试数据。 对每一组测试数据,第一行是两个数n(1<=n<=10^6)和m(0<=m<=10^5),用空格分隔。
接下来的m行中每一行包含三个数L,R和a(0<=L<=R<=n-1,0<=a<=100),用空格分隔,表示一个操作。
输出格式
对于每组测试数据输出一行,所有实验操作后所有光照了奇数天的植物总的高度
代码如下:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int val[1000050];
int main()
{
int T,n,l,r,a,m,sum,ans;
scanf("%d",&T);
while(T--)
{
memset(val,0,sizeof(val));
scanf("%d %d",&n,&m);
for(int i = 0;i<m; i++)
{
scanf("%d %d %d",&l,&r,&a);
val[l] += a;
val[r+1] -= a;
}
sum = 0; ans = 0;
for(int i = 0;i<=n+1;i++)
{
sum += val[i];
if(sum%2==1)
ans += sum;
}
printf("%d\n",ans);
}
return 0;
}
Codeforces Round #376 (Div. 2) D. 80-th Level Archeology —— 差分法 + 线段扫描法的更多相关文章
- Codeforces Round #538 (Div. 2) F 欧拉函数 + 区间修改线段树
https://codeforces.com/contest/1114/problem/F 欧拉函数 + 区间更新线段树 题意 对一个序列(n<=4e5,a[i]<=300)两种操作: 1 ...
- Codeforces Round #376 (Div. 2) C题 Socks(dsu+graphs+greedy)
Socks Problem Description: Arseniy is already grown-up and independent. His mother decided to leave ...
- Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)
题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...
- Codeforces Round #376 (Div. 2) C. Socks---并查集+贪心
题目链接:http://codeforces.com/problemset/problem/731/C 题意:有n只袜子,每只都有一个颜色,现在他的妈妈要去出差m天,然后让他每天穿第 L 和第 R 只 ...
- Codeforces Round #376 (Div. 2) F. Video Cards 数学 & 暴力
http://codeforces.com/contest/731/problem/F 注意到一个事实,如果你要找一段区间中(从小到大的),有多少个数是能整除左端点L的,就是[L, R]这样.那么,很 ...
- Codeforces Round #376 (Div. 2) F. Video Cards —— 前缀和 & 后缀和
题目链接:http://codeforces.com/contest/731/problem/F F. Video Cards time limit per test 1 second memory ...
- Codeforces Round #376 (Div. 2) A. Night at the Museum —— 循环轴
题目链接: http://codeforces.com/contest/731/problem/A A. Night at the Museum time limit per test 1 secon ...
- Codeforces Round #376 (Div. 2) C. Socks —— 并查集 + 贪心
题目链接:http://codeforces.com/contest/731/problem/C 题解: 1.看题目时,大概知道,不同的袜子会因为要在同一天穿而差生了关联(或者叫相互制约), 其中一条 ...
- Codeforces Round #376 (Div. 2)
A 模拟 #include <cstdio> #include <cstring> int Ans; ]; inline ?x:-x;} inline int Min(int ...
随机推荐
- python使用Queue进行进程间通信
1.Process之间有时需要通信,操作系统提供了很多机制来实现进程间的通信. 可以使用multiprocessing模块的Queue实现多进程之间的数据传递, Queue本身是一个消息列队程序: f ...
- Spring配置项之<aop:aspectj-autoproxy />
通过配置织入@Aspectj切面 虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作. 通过aop命名空间的<aop:aspectj-a ...
- 微信小程序提交 webapi FormDataCollection
/// <returns></returns> [HttpPost] public ShoppingCartModel UpdateCart(FormDataCollectio ...
- Objc的底层并发API(转)
本文由webfrogs译自objc.io,原文作者Daniel Eggert. 小引 本篇英文原文所发布的站点objc.io是一个专门为iOS和OS X开发者提供的深入讨论技术的平台,文章含金量很 ...
- 临远的activiti教程
1. 简介 协议 下载 源码 必要的软件 JDK 6+ Eclipse Indigo 和 Juno 报告问题 试验性功能 内部实现类 2. 开始学习 一分钟入门 安装Activiti 安装Activi ...
- jquery 查找子元素的几种方法
<div class="tm-clear tb-hidden tm_brandAttr" id="J_BrandAttr" style="dis ...
- 【Hibernate步步为营】--核心对象+持久对象全析(三)
上篇文章讨论了Hibernate持久对象的生命周期,在整个生命周期中一个对象会经历三个状态,三种状态的转换过程在开发过程中是可控的.并且是通过用法来控制它们的转化过程.详细的转化过程今天就来着重讨论下 ...
- meta标签多种用法
<meta name=”google” content=”notranslate” /> <!-- 有时,Google在结果页面会提供一个翻译链接,但有时候你不希望出现这个链接,你可 ...
- 蜗牛—Android基础之button监听器
XML文件中有一个textView 和 一个button. <LinearLayout xmlns:android="http://schemas.android.com/apk/re ...
- C语言函数的递归和调用
函数记住两点: (1)每个函数运行完才会返回调用它的函数:每个函数运行完才会返回调用它的函数,因此,你可以先看看这个函数不自我调用的条件,也就是fun()中if条件不成立的时候,对吧,不成立的时候就是 ...