码迷,mamicode.com
首页 > 其他好文 > 详细

【codeforces #285(div 1)】

时间:2015-01-14 09:53:34      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:oi   codeforces   

打完这场,从紫名回到蓝名了技术分享


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?-?10?≤?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?-?10?≤?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;
}

技术分享


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


【codeforces #285(div 1)】

标签:oi   codeforces   

原文地址:http://blog.csdn.net/regina8023/article/details/42688833

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!