Uva https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4965
vjudge https://vjudge.net/problem/UVALive-6953
雾草 一波瞎优化从2000ms跑到800ms.....
题意:给你n(1~10^18)个球 m个点 每个点有一个状态 一个球来过状态就改变 根据当前状态确定下一步(状态左右)
输入 m行 : 初始状态 左子树 右子树
直接模拟会超时
利用拓扑思想 记录入度 然后队列模拟
首先几点必须注意
1.落下偶数小球 状态不变
2.落下奇数小球 状态改变
3.左右子树 可以相同(左右子树描述不确切)
4.入度为零的点可能不只是1节点
详见下代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <ctime>
#include <map>
using namespace std;
#define sf scanf
#define pf printf
#define ll long long
#define For(i,a,b) for(i=a;i<=b;i++)
#define _For(i,a,b) for(i=b;i>=a;i--)
#define Out(x) cout<<x<<endl
#define Outdouble(x,a) cout<<fixed<<setprecision(a)<<1.0*x<<endl
#define mset(arr,num) memset(arr,num,sizeof(arr))
#define ok std::ios::sync_with_stdio(0)
#pragma comment(linker, "/STACK:102400000,102400000")
#pragma GCC optimize("O3")
const ll inf = 1e12+10; ///
const double esp = 1e-7; ///
const int NUM = 1e5+10;
// #define debug
#if defined (debug)
---check---
#endif
/// ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ^_^ ///
struct node
{
ll num;
int dis; ///1表示Left 0表示Right
int l,r;
} arr[5*NUM];
int indeg[5*NUM]; ///存入度
ll n,m; ///long long 把我卡炸了
void bfs()
{
int i,past;
queue <int> q;
For(i,1,m) ///注意 如果某点入度为零也要加进来 因为关系到后面节点的入度--问题
{
if(indeg[i]==0)
{
q.push(i);
}
}
while(!q.empty())
{
past = q.front();
q.pop();
int L = arr[past].l;
int R = arr[past].r;
arr[L].num+=arr[past].num>>1;
arr[R].num+=arr[past].num>>1;
if((arr[past].num&1) == 1) ///如果小球是奇数那么多出来的一个判断分给谁
{
if(arr[past].dis == 1) ///根据父节点来判断当前状态
{
arr[L].num++;
}
else
{
arr[R].num++;
}
arr[past].dis^=1; ///转换状态
} ///当落上珠子和是偶数那么并不会变状态
arr[past].num = 0;
indeg[L]--;
indeg[R]--; ///入度减一 父节点"释放"
if(L!=0 && indeg[L]==0) ///只要不为零,入度为零 那么前面就没有球落进来了 状态就固定了
{
q.push(L);
if(L == R) continue; ///左右孩子相同的情况 记得判断
}
if(R!=0 && indeg[R]==0)
{
q.push(R);
}
}
}
void Output()
{
int i;
For(i,1,m)
{
if(arr[i].dis == 1)
{
pf("L");
}
else pf("R");
}
pf("\n");
}
int main()
{
ok;
char s[5];
int i,j;
while(cin>>n>>m)
{
mset(indeg,0);
mset(arr,0);
For(i,1,m)
{
cin>>s>>arr[i].l>>arr[i].r;
indeg[arr[i].l]++;
indeg[arr[i].r]++; ///记录入度
if(s[0] == 'L')
{
arr[i].dis = 1;
}
else arr[i].dis = 0;
}
arr[1].num = n; ///n个球放在1上
bfs();
Output();
}
return 0;
}