QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#472772 | #5504. Flower Garden | yz_ly | RE | 0ms | 0kb | C++14 | 4.4kb | 2024-07-11 19:15:34 | 2024-07-11 19:15:34 |
answer
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int f=1,x=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return f*x;
}
inline void work(int k){
if(k<0){
putchar('-');
k=-k;
}
if(k>9)
work(k/10);
putchar(k%10+'0');
}
/*
首先不难想到2-sat,然后线段树优化建图后缩点,发现建图只用考虑s[x]=1->s[y]=1的部分,其余部分不用考虑
现在相当于有一个有点权的DAG,要求把DAG分成两半使得两边的点权都在[n,2*n]之内
如果有点>2*n肯定就无解
如果有一个点>=n,那么枚举这个点和前驱还是和后继在一起就行了
否则所有点都<n,直接按拓扑序一个一个点加进去,什么时候满足要求停下就行了
*/
int t,n,q,cnt,first[2000005],num,dfn[2000005],low[2000005],co[2000005],siz[2000005],vis[2000005],l,now,id[2000005],sum,ans[2000005],d[2000005],cnt1,first1[2000005];
stack<int> s;
struct q1{
int u,w,nex;
}a[10000005],b[10000005];
void add(int u1,int w1){
a[++cnt]={u1,w1,first[u1]};
first[u1]=cnt;
}
void add1(int u1,int w1){
b[++cnt1]={u1,w1,first1[u1]};
first1[u1]=cnt1;
}
struct node{
void build(int k,int l,int r){
add(k+8*n,k);
if(l==r){
id[l]=k;
return ;
}
int mid=(l+r)>>1;
build(2*k,l,mid);
build(2*k+1,mid+1,r);
add(2*k,k);
add(2*k+1,k);
add(k+8*n,2*k+8*n);
add(k+8*n,2*k+1+8*n);
}
void change(int k,int l,int r,int x,int y){
if(l>y||r<x)
return ;
if(l>=x&&r<=y){
add(k,num);
return ;
}
int mid=(l+r)>>1;
change(2*k,l,mid,x,y);
change(2*k+1,mid+1,r,x,y);
}
void modify(int k,int l,int r,int x,int y){
if(l>y||r<x)
return ;
if(l>=x&&r<=y){
add(num,k+8*n);
return ;
}
int mid=(l+r)>>1;
modify(2*k,l,mid,x,y);
modify(2*k+1,mid+1,r,x,y);
}
}tree;
void Tarjan(int u){
s.emplace(u);
vis[u]=1;
dfn[u]=low[u]=++now;
for(int i=first[u];i;i=a[i].nex){
if(!dfn[a[i].w]){
Tarjan(a[i].w);
low[u]=min(low[u],low[a[i].w]);
}
else if(vis[a[i].w])
low[u]=min(low[u],dfn[a[i].w]);
}
if(dfn[u]==low[u]){
co[u]=++l;
vis[u]=0;
while(s.top()!=u){
co[s.top()]=l;
vis[s.top()]=0;
s.pop();
}
s.pop();
}
}
void solve(int u){
vis[u]=1;
sum+=siz[u];
for(int i=first[u];i;i=a[i].nex){
if(!vis[a[i].w])
solve(a[i].w);
}
}
int main(){
t=read();
while(t--){
n=read();
q=read();
num=16*n;
cnt=0;
for(int i=1;i<=num;i++){
first[i]=dfn[i]=low[i]=vis[i]=0;
}
tree.build(1,1,3*n);
while(q--){
int x=read(),y=read(),l=read(),r=read();
num++;
first[num]=dfn[num]=low[num]=vis[num]=0;
tree.change(1,1,3*n,x,y);
tree.modify(1,1,3*n,l,r);
}
now=l=0;
for(int i=1;i<=num;i++){
if(!dfn[i])
Tarjan(i);
}
for(int i=1;i<=l;i++){
siz[i]=0;
}
for(int i=1;i<=3*n;i++){
siz[co[id[i]]]++;
}
int flag=0;
for(int i=1;i<=l;i++){
if(siz[i]>2*n){
flag=1;
break;
}
}
if(flag){
puts("NIE");
continue;
}
int all=cnt;
cnt=cnt1=0;
for(int i=1;i<=num;i++){
first[i]=first1[i]=d[i]=0;
}
for(int i=1;i<=all;i++){
if(co[a[i].u]!=co[a[i].w]){
d[co[a[i].u]]++;
add1(co[a[i].w],co[a[i].u]);
add(co[a[i].u],co[a[i].w]);
}
}
int id1=0;
for(int i=1;i<=l;i++){
vis[i]=0;
if(siz[i]>=n)
id1=i;
}
sum=0;
if(id1){
solve(id1);
vis[id1]=0;
sum-=siz[id1];
if(siz[id1]>=n&&sum>=n)
exit(1);
if(sum>=n){
for(int i=1;i<=3*n;i++){
if(vis[co[id[i]]])
ans[i]=1;
else
ans[i]=0;
}
}
else if(siz[id1]+sum<=2*n){
for(int i=1;i<=3*n;i++){
if(vis[co[id[i]]]||co[id[i]]==id1)
ans[i]=1;
else
ans[i]=0;
}
}
else{
puts("NIE");
continue;
}
}
else{
queue<int> p;
for(int i=1;i<=l;i++){
if(!d[i])
p.emplace(i);
}
while(!p.empty()){
int k=p.front();
p.pop();
sum+=siz[k];
vis[k]=1;
if(sum>=n)
break;
for(int i=first1[k];i;i=b[i].nex){
if(!(--d[b[i].w]))
p.emplace(b[i].w);
}
}
for(int i=1;i<=3*n;i++){
if(vis[co[id[i]]])
ans[i]=1;
else
ans[i]=0;
}
}
puts("TAK");
for(int i=1;i<=3*n;i++){
putchar(ans[i]?'F':'R');
}
putchar('\n');
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
2 1 3 1 1 2 2 1 2 3 3 1 1 3 3 1 3 1 1 2 2 2 2 3 3 3 3 1 1