【codeforces #285(div 1)】

打完这场,从紫名回到蓝名了

A. Misha and Forest

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Let‘s define a forest as a non-directed acyclic graph (also without loops and parallel edges). One day Misha played with the forest consisting of n vertices.
For each vertex v from 0 to n?-?1 he
wrote down two integers, degreev and sv,
were the first integer is the number of vertices adjacent to vertex v, and the second integer is the XOR sum of the numbers of vertices adjacent to v (if
there were no adjacent vertices, he wrote down 0).

Next day Misha couldn‘t remember what graph he initially had. Misha has values degreev and sv left,
though. Help him find the number of edges and the edges of the initial graph. It is guaranteed that there exists a forest that corresponds to the numbers written by Misha.

Input

The first line contains integer n (1?≤?n?≤?216),
the number of vertices in the graph.

The i-th of the next lines contains numbers degreei and si (0?≤?degreei?≤?n?-?1, 0?≤?si?<?216),
separated by a space.

Output

In the first line print number m, the number of edges of the graph.

Next print m lines, each containing two distinct numbers, a and b (0?≤?a?≤?n?-?1, 0?≤?b?≤?n?-?1),
corresponding to edge (a,?b).

Edges can be printed in any order; vertices of the edge can also be printed in any order.

Sample test(s)

input

3
2 3
1 0
1 0

output

2
1 0
2 0

input

2
1 1
1 0

output

1
0 1

考试中只做出来第一题。。

这道题就是利用了a^b^b=a这个性质。

每次对于度数只剩1的点x直接输出他的连边,并且把与x相连的这个点度数-1,并异或上x,那么就消除了x对与x相连的那个点的影响。

一开始没想到用队列来做。。一直WA+TLE..

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <queue>
using namespace std;
int n,now,fr[100005],to[100005];
struct data
{
	int d,s;
}a[100005];
queue<int> q;
int main()
{
        scanf("%d",&n);
	for (int i=0;i<n;i++)
	{
		scanf("%d%d",&a[i].d,&a[i].s);
		now+=a[i].d;
		if (a[i].d==1) q.push(i);
	}
	cout<<now/2<<endl;
	now=0;
	while (!q.empty())
	{
		int x=q.front();
		q.pop();
		if (a[x].d==1)
		{
			int v=a[x].s;
			fr[++now]=x,to[now]=v;
			a[v].d--;
			a[v].s^=x;
			if (a[v].d==1) q.push(v);
		}
	}
	for (int i=1;i<=now;i++)
		printf("%d %d\n",fr[i],to[i]);
	return 0;
}

B. Misha and Permutations Summation

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Let‘s define the sum of two permutations p and q of
numbers 0,?1,?...,?(n?-?1) as permutation ,
where Perm(x) is the x-th lexicographically
permutation of numbers 0,?1,?...,?(n?-?1) (counting from zero), and Ord(p) is
the number of permutation p in the lexicographical order.

For example, Perm(0)?=?(0,?1,?...,?n?-?2,?n?-?1), Perm(n!?-?1)?=?(n?-?1,?n?-?2,?...,?1,?0)

Misha has two permutations, p and q. Your task is
to find their sum.

Permutation a?=?(a0,?a1,?...,?an?-?1) is
called to be lexicographically smaller than permutation b?=?(b0,?b1,?...,?bn?-?1),
if for some k following conditions hold: a0?=?b0,?a1?=?b1,?...,?ak?-?1?=?bk?-?1,?ak?<?bk.

Input

The first line contains an integer n (1?≤?n?≤?200?000).

The second line contains n distinct integers from 0 to n?-?1,
separated by a space, forming permutation p.

The third line contains n distinct integers from 0 to n?-?1,
separated by spaces, forming permutation q.

Output

Print n distinct integers from 0 to n?-?1,
forming the sum of the given permutations. Separate the numbers by spaces.

Sample test(s)

input

2
0 1
0 1

output

0 1

input

2
0 1
1 0

output

1 0

input

3
1 2 0
2 1 0

output

1 0 2

Note

Permutations of numbers from 0 to 1 in the lexicographical order: (0,?1),?(1,?0).

In the first sample Ord(p)?=?0 and Ord(q)?=?0,
so the answer is .

In the second sample Ord(p)?=?0 and Ord(q)?=?1,
so the answer is .

Permutations of numbers from 0 to 2 in the lexicographical order: (0,?1,?2),?(0,?2,?1),?(1,?0,?2),?(1,?2,?0),?(2,?0,?1),?(2,?1,?0).

In the third sample Ord(p)?=?3 and Ord(q)?=?5,
so the answer is .

这道题考试中只想到O(nlog^2n)的做法,是二分+树状数组。与标解一步之遥。。

通过观察发现一个数列排在第几位,就是a1*(n-1)!+a2*(n-2)!+......an*0!,其中ai是指第i位所填的数比除掉之前所填的数

中剩下的数中ai个大,很明显要用树状数组。

两个数列的和其实就是ci=ai+bi,再处理一下进位就好(对于mod n!也就同时处理了)。

接下来就是如何通过ci来生成答案了。

我当时的想法是二分每一位(程序中被注释掉的部分),这样是超时的。。

应该充分利用一下树状数组的特点,有点像是倍增一样往上走,这样来做就是O(nlogn)了。(这个方法非常值得借鉴)

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
int v[200005],b[200005],t[200005],a[200005],x[200005],y[200005],now[200005],n;
int lowbit(int x)
{
	return x&(-x);
}
void Update(int x,int v)
{
	for (int i=x;i<=n;i+=lowbit(i))
		t[i]+=v;
}
int Getsum(int x)
{
	int ans=0;
	for (int i=x-1;i;i-=lowbit(i))
		ans+=t[i];
	return ans;
}
/*int Get(int k)
{
	int l=1,r=n;
	while (1)
	{
		int m=(l+r)>>1;
		int p=Getsum(m);
		if (p==k)
		{
			if (!v[m]) return m;
			else l=m+1;
			continue;
		}
		if (p<k) l=m;
		else r=m;
	}
}*/
int Get(int k)
{
	int ans=0,now=0;
	for (int i=20;i>=0;i--)
		if (ans+(1<<i)>n||now+t[ans+(1<<i)]>=k)
			continue;
	        else
		{
			now+=t[ans+(1<<i)];
			ans+=(1<<i);
		}
	return ans+1;
}
int main()
{
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&a[i]),a[i]++;
	for (int i=1;i<=n;i++)
		scanf("%d",&b[i]),b[i]++;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		x[i]=Getsum(a[i]),Update(a[i],-1);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	for (int i=1;i<=n;i++)
		y[i]=Getsum(b[i]),Update(b[i],-1);
	for (int i=n;i>1;i--)
	{
		now[i]=now[i]+x[i]+y[i];
		if (now[i]>n-i) now[i]=now[i]-n+i-1,now[i-1]++;
	}
	now[1]=now[1]+x[1]+y[1];
	if (now[1]>=n) now[1]-=n;
	printf("%d ",now[1]);
	for (int i=1;i<=n;i++)
		t[i]=0;
	for (int i=1;i<=n;i++)
		Update(i,1);
	v[now[1]+1]=1;
	Update(now[1]+1,-1);
	for (int i=2;i<=n;i++)
	{
		int x=Get(now[i]+1);
		printf("%d ",x-1);
		Update(x,-1);
		v[x]=1;
	}
	return 0;
}

感悟:

1.这次比赛感觉自己思路比较混乱,代码能力也很差。。

2.对于B题中对于答案数列的求解,逆用了树状数组的性质,就像是求一个二进制数一样求出了前缀和!!

时间: 2024-09-30 14:33:48

【codeforces #285(div 1)】的相关文章

【codeforces #299(div 1)】ABC题解

A. Tavas and Karafs time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Karafs is some kind of vegetable in shape of an 1?×?h rectangle. Tavaspolis people love Karafs and they use Karafs in almost

【codeforces #283(div 1)】ABC题解

A. Removing Columns time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output You are given an n?×?m rectangular table consisting of lower case English letters. In one operation you can completely r

【codeforces #284(div 1)】ABC题解

A. Crazy Town time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Crazy Town is a plane on which there are n infinite line roads. Each road is defined by the equation aix?+?biy?+?ci?=?0, where 

【codeforces #282(div 1)】AB题解

A. Treasure time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Malek has recently found a treasure map. While he was looking for a treasure he found a locked door. There was a string s writte

【codeforces #292(div 1)】ABC题解

A. Drazil and Factorial time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Drazil is playing a math game with Varda. Let's define  for positive integer x as a product of factorials of its dig

【codeforces #296(div 1)】ABD题解

A. Glass Carving time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Leonid wants to become a glass carver (the person who creates beautiful artworks by cutting the glass). He already has a rectan

【codeforces #278(div 1)】ABCD题解

A. Fight the Monster time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output A monster is attacking the Cyberland! Master Yang, a braver, is going to beat the monster. Yang and the monster each hav

【codeforces #286(div 2)】ABCD题解

这次rank23~又回到紫名啦~ A.枚举插入的位置和插入的字符,暴力判断即可. #include <iostream> #include <cmath> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <string> using namespace std; string S; int s[20]

【codeforces 718 C&amp;D】C. Sasha and Array&amp;D. Andrew and Chemistry

C. Sasha and Array 题目大意&题目链接: http://codeforces.com/problemset/problem/718/C 长度为n的正整数数列,有m次操作,$opt==1$时,对$[L,R]$全部加x,$opt==2$时,对$[L,R]$求$\sum_{i=L}^{R}Fibonacc(a_{i})$. 题解: 线段树+矩阵快速幂. 在每个线段树存一个转移矩阵,然后YY即可. 代码: 1 #include<cstdio> 2 #include<cs