《本题不卡常》,请求开大时限!!!

P3806 【模板】点分治 1

Morgen_Kornblume @ 2021-05-27 23:37:23

卡死了,对C++STL壬极其不友好!!!

最后三个Subtask全部超时大约100ms以内!

复杂度正确,常数感人的典型!

下贴被卡代码:

#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
#include<stdio.h>
#include<deque>
#include<cstring>
#include<map>
#include<utility>
using namespace std;
int n,m;
const int maxn=10010;
deque<pair<int,int> >que;
bool ans[110];
map<int,bool>mmp;

struct graph{
    int tot;
    int head[maxn],to[maxn],wei[maxn],nxt[maxn];
    int size;int root;int sub[maxn];int maxx;
    int dist[maxn];
    int sta[maxn];
    int top;
    int vis[maxn];

    void init(){
        tot=0;
        memset(head,0,sizeof(head));
    }

    void add(int x,int y,int z){
        tot++;
        nxt[tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        wei[tot]=z;
    }

    void cul(int x,int fa){
        sta[++top]=dist[x];
        int opt=(int)que.size();
        for(int i=1;i<=opt;i++){
            pair<int,int>tmp=que.front();
            que.pop_front();
            if(ans[tmp.second])continue;
            if(tmp.first-dist[x]<0){
                que.push_back(tmp);continue;
            }
            if(mmp.find(tmp.first-dist[x])!=mmp.end()){
                ans[tmp.second]=true;
                continue;
            }
            que.push_back(tmp);
        }
        for(int i=head[x];i;i=nxt[i]){
            int go=to[i];
            if(vis[go]||go==fa){
                continue;
            }
            cul(go,x);
        }
    }

    void getroot(int x,int fa){
        sub[x]=1;
        int inmax=0;
        for(int i=head[x];i;i=nxt[i]){
            int go=to[i];
            if(vis[go]||go==fa){
                continue;
            }
            getroot(go,x);
            sub[x]+=sub[go];
            inmax=max(inmax,sub[go]);
        }
        inmax=max(inmax,size-sub[x]);
        if(inmax<maxx){
            maxx=inmax;
            root=x;
        }
    }

    void getdist(int x,int fa){

        for(int i=head[x];i;i=nxt[i]){
            int go=to[i];
            if(vis[go]||go==fa)continue;
            dist[go]=dist[x]+wei[i];
            getdist(go,x);
        }

    }

    void solve(int x){
        maxx=0x7fffffff;
        root=x;
        getroot(x,0);
        x=root;vis[x]=1;dist[x]=0;mmp.clear();
        getdist(x,0);
        mmp[0]=true;

        for(int i=head[x];i;i=nxt[i]){
            int go=to[i];
            if(vis[go])continue;
            cul(go,x);
            while(top)mmp[sta[top--]]=true;
        }

        for(int i=head[x];i;i=nxt[i]){
            int go=to[i];
            if(vis[go])continue;
            size=sub[go];
            solve(go);
        }
    }
}g;

int main(){
    que.clear();
    memset(ans,false,sizeof(ans));

    scanf("%d%d",&n,&m);

    int uu,vv,ww;
    for(int i=1;i<n;i++){
        scanf("%d%d%d",&uu,&vv,&ww);
        g.add(uu,vv,ww);
        g.add(vv,uu,ww);
    }
    int tmp;
    for(int i=1;i<=m;i++){
        scanf("%d",&tmp);
        que.push_back(make_pair(tmp,i));
    }
    g.size=n;
    g.solve(1);

    for(int i=1;i<=m;i++){
        (ans[i])?(puts("AYE")):(puts("NAY"));
    }

    return 0;
}

by pocafup @ 2021-05-27 23:49:48

为啥用map复杂度正确啊?


by Singercoder @ 2021-05-28 00:39:45

能用桶就别开map啦


by SSerxhs @ 2021-05-28 01:26:10

《复杂度正确》


by Aleph1022 @ 2021-05-28 07:19:46

为啥用 map 复杂度正确啊?


by __OwO__ @ 2021-05-28 08:26:44

为啥用 map 复杂度正确啊?


by PY_Fighter @ 2021-05-28 09:27:27

昨天写Tree我吸氧才勉强过去…… 刚刚写聪聪可可吸氧还是T了两个点,一个1.04s一个1.02s……绝望 点分治有没有什么卡常的技巧啊


by chen_qian @ 2021-05-28 10:00:36

@PY_Fighter 是吗,那几个题都不卡常


by PY_Fighter @ 2021-05-28 10:07:56

@chen_qian 我不知道是不是我代码写的太烂还是咋地……每次分治里面除了排序O(nlogn)其余应该是严格O(n),自己感觉常数也不大,我也想知道为什么


by _lbw_ @ 2021-05-28 10:25:25

@PY_Fighter 为啥点分治要排序


by PY_Fighter @ 2021-05-28 10:32:41

@lbw 我写排序的拿到是Tree,就是把点分治1的判断=k改成<=k的有几个与POJ1741大致相同(输入格式不同),我把那道题当做点分治模板做的


| 下一页