2019년 9월 8일 팀 측정

T1 :

대피 마법사
(shelter.cpp 1S 256M)
"큰 뉴스, 큰 뉴스! 끔찍한 바이러스의 전국 확산은 거대한에!이 나라의 여러 도시에서 확산하기 시작했다
패닉에! 위기 주민의 많은 수를하고 싶어 조사는 불법의 학교의 도시에서 C 바이러스가 ... 밝혀! 피신 해 다른 도시로 도망
... ""이봐. "당신이 TV를 끄고 한숨을 내 쉬었다. 학교의 교장, 자신의 삶에 대한 전에 하루는 혼자 학교를 탈출 학교를 포기
하면 계산 및 도로 엔지니어를 해체 도울 수있는 사람을 포함하여 교사와 학생을. 당신의 양심, 그것이 어떤 치료를하기로 결정했다, 엄청난 비난하고 A가 응답 한
사람들이 제안 도망 부탁드립니다. 국가, n은 도시의 총에 알려진, 그리고 제 1의 수도 도시입니다. (N-1) 양방향이 도시 연결 도로
하나 개의 경로 만 두 도시 간의 이러한 도로하고있다. 각 도로는 길이를 가지고있다. 도시 도로 만 상 경우
회사는 다음 국경 도시를했다. 정부는 이상한 요구 사항이 각 도시가 폐쇄 계수 디를 가지고, 디는 도시에서 멀리 멀리로 정의된다
도시에서 도시로 국경. 시민들은 도시의 안전 계수와 감금 계수시 매우 중요한 링크를 가지고 있다고 생각합니다. A, B는 C는
나라에서 행운의 숫자입니다, 그래서 우리는 * 도시시 =의 안전 계수를 받아 (디 +) B 모드 다. 시민들은 m 번 문의 총을 올릴 것이다
. 각각의 세 가지 정보 조회, XI, 순이와 제나라가 포함되어 있습니다. XI 도시 수 조사자이다. 당신은을 통해 통과해야 XI 이순신의 조사자로 이동
피난처의 가장 가까운 도시에서 출산 할 수있는 방법을 찾아 피난 제나라의이 도시에 안전 계수보다 크거나 같은 필요합니다. 도시 (함유 있으면
XI 및 일), 출력 수 도시 달리 출력 라인들을 포함 -1.
입력
다섯 개 값의 첫 번째 라인 : N, m, A, B,이어서 하였다.
다음에, N-1 행 기술 정보 고속도로.
세 개의 숫자의 각 행은 처음 두 숫자는이 도로 연결 번호, 세 번째 숫자는 도로의 길이를 나타내는 두 도시를 나타냅니다.
다음의 m 행은, 각 열은 세 개의 숫자 XI 이순신 치와를 포함하는 쿼리를 설명한다.
0 <XI <= N-
치 <= 1000000
N - <= 100000
m <300000 =
중간 64 비트 정수 걸릴 수 안전율
출력
각각의 쿼리는, 상기 출력 라인은 정수를 포함 존재 도시 도시 ID의 요구를 충족시키기 출력 -1의 출력은 존재하지 않는다.
샘플 입력
. 7. 제 5 6 내지 20이다
. 1 2 4
2 4 2
2 5 3
. 1. 3. 5
. 3. 6.6
. 6. 7. 7
. 7. 5 (15)
. 3. 4. 5
. 제 4 2
. 제 5 2
. 6. 6~10
. 3. 제 19
샘플 출력
. 6
. 3
(2)
. (4)
. 6
-1

해결책:

각 포인트에 대한, 그에게서 포인트 먼 엔드 포인트의 직경해야하기 때문에 첫째, 우리는, 직경에 의해 안전 계수를 추구 할 수

우리는 선조 경로에 대한 안전 계수의 최대 값을 나타내는 사전 승산기 어레이 MX 배열에 따른 전처리 방법을

다음 줄에 최종 출력에, y로 LCA 다시 대답을 요구하지 않을 경우마다 결정 LCA (x, y)는 다음 X LCA 다시 추구

암호:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1;
int n,m,cnt,a,b,c,V,head[N];
int Mx,st,ed,dis[N],d[N];
int f[N][31],mx[N][31],dep[N];
struct Edge{int nxt,to,val;}edge[N<<1];
void ins(int x,int y,int z){
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;head[x]=cnt;
    edge[cnt].val=z;
}
void getdis(int x,int fa){
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(y==fa) continue;
        int tmp=dis[y];
        dis[y]=dis[x]+edge[i].val;
        if(tmp>dis[y]) d[y]=tmp;
        else d[y]=dis[y];
        if(dis[y]>dis[Mx]) Mx=y;
        getdis(y,x);
    }
}
void dfs(int x,int fa){
    mx[x][0]=d[x];dep[x]=dep[fa]+1;
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(y==fa) continue;
        f[y][0]=x;dfs(y,x);
    }
}
void trans(){
    for(int i=1;i<=21;i++)
        for(int j=1;j<=n;j++){
            f[j][i]=f[f[j][i-1]][i-1];
            mx[j][i]=max(mx[j][i-1],mx[f[j][i-1]][i-1]);
        }
}
int lca(int x,int y){
    if(dep[x]<dep[y]) swap(x,y);
    if(x==y||y==1) return y;
    for(int i=21;i>=0;i--)
        if(dep[f[x][i]]>=dep[y]) x=f[x][i];
    if(x==y) return x;
    for(int i=21;i>=0;i--)
        if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
int find1(int x,int fa){
    int ff=f[fa][0];
    for(int i=21;i>=0;i--){
        int u=f[x][i];
        if(dep[u]<dep[ff]) continue;
        if(mx[x][i]<V) x=u;
    }return x==ff?-1:x;
}
int jump(int x,int fa){
    int ff=f[fa][0];
    for(int i=21;i>=0;i--){
        int u=f[x][i];
        if(dep[u]<dep[ff]) continue;
        if(mx[x][i]>=V) return 1;x=u;
    }return 0;
}
int find2(int x,int fa){
    if(!jump(x,fa))return -1;
    for(int i=21;i>=0;i--){
        int u=f[x][i];
        if(jump(u,fa)) x=u;
    }return x;
}
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
signed main(){
    n=read(),m=read();
    a=read(),b=read(),c=read();
    for(int i=1;i<n;i++){
        int x=read(),y=read(),z=read();
        ins(x,y,z),ins(y,x,z);
    }
    getdis(1,0);st=Mx;Mx=0;dis[st]=0;
    getdis(st,0);ed=Mx;Mx=0;dis[ed]=0;
    getdis(ed,0);Mx=0;
    for(int i=1;i<=n;i++) d[i]=(d[i]+a)*1ll*b%c;
    dfs(1,0);trans();
    for(int i=1;i<=m;i++){
        int x=read(),y=read();V=read();
        int fart=lca(x,y),ans=-1;
        if(d[x]>=V) ans=x;
        if(ans==-1) ans=find1(x,fart);
        if(ans==-1){
            if(d[fart]>=V){ans=fart;goto Out;}
            ans=find2(y,fart);
        }Out:printf("%lld\n",ans);
    }return 0;
}

T2 :

애니메이션 정렬
(sort.cpp의 1 초 256M)
수많은 애니메이션이 있지만 작은 WW는 최근, 일본 애니메이션과 사랑에 빠진 그를보고 기다리고 매일 수많은 애니메이션을 업데이트, 그래서 그는 물론, 모든 애니메이션을 연속 행을했다 하지만, 제 1의 애니메이션뿐만 아니라, 모든 부서에만 만화 애니메이션은 전편 (아버지)가, 그 애니메이션의 모든 트리 구조를 형성, 말을하는 것입니다. : 애니메이션의 순서는 다음과 같은 두 가지 제한 충족해야합니다
모든 후속 ① 애니메이션 (후손) 뒤에 순위가되어야합니다.
애니메이션 (어린이)와 속편, 작은 W 높은 사랑을 위해 ②는 앞에 서있다.
작은 빛의 WW 정렬도 불행, 그는 총 주문 방식의 얼마나 많은 종을 알고 싶어,하고의 응답 mod10007를 출력합니다.
입력
첫 번째 행 T는 데이터의 개수를 나타내는기를 나타낸다.
다음에, 각각 첫 번째 행의 데이터와 해당 애니메이션 대기 유닛 넘버 소팅 나타내는
다음 N 라인 A 본 애니메이션 번호 속편 TOT 첫 번째 숫자로 표시 각
WW 내림차순 작은 좋아의 수에 따라 다음 TOT 그 속편 번호를 부여.
n≤1000.
출력
각 데이터 줄 번호 ANS의는 응답의 결과가 mod10007 보여줍니다.
입력 샘플
. 1
. 5
. 3. 제 3 2
0
. 1 5
0
0
샘플 출력
2

해결책:

우리는 우리에게 두 가지 한계에서, 우리가지도를 재구성 할 수 있음을 발견보고

우리는 접속 측의 순서의 아들을 가리킬 수, 즉 \ (son_i \)\ (son_이 {내가 + 1} \) 대신 측에 접속 \ (X \) 에 연결되어있는 에지 이와 같이 동등

그럼 설정 \ ([X] \ F)를 대표하는 \ (X \) 서브 트리의 루트 적법한 순회 차수 다음 \ ([1] \ F) 최종 응답은

이진 트리 뷰가 잘 전송되는, 복원되어야하므로 : \ (F [X] = F [son_1] \ F 시간 [son_2] \ {C_ 시간 SZ [son_1] + SZ [son_2]} ^ SZ {[son_1]} \)

제 번호의 마지막 순열 프로그램의 수를 순서화 삽입하는 제 2 프로그램 번호를 나타내는 것을 특징으로하는, 즉, 카드 법

마지막으로, 우리는 MOD 것을 기억해야한다

암호:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1;
const int p=1e4+7;
int n,cnt,head[N],sz[N],f[N],fac[N];
struct Edge{int nxt,to;}edge[N<<1];
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
void ins(int x,int y){
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;head[x]=cnt;
}
int qpow(int a,int b){
    int re=1;
    while(b){
        if(b&1) re=(re*1ll*a)%p;
        b=b>>1;a=(a*1ll*a)%p;
    }return re%p;
}
int C(int x,int y){
    int re=fac[x];
    re=(re*1ll*qpow(fac[y],p-2))%p;
    re=(re*1ll*qpow(fac[x-y],p-2))%p;
    return re;
}
void format(){
    cnt=0;
    memset(head,0,sizeof(head));
}
void dfs(int x,int fa){
    f[x]=1;sz[x]=1;
    int s[2],a[2],flag=0;
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(y==fa) continue;
        dfs(y,x);sz[x]+=sz[y];
        s[flag++]=sz[y];
        a[flag-1]=f[y];
    }
    if(flag==1) f[x]=a[0];
    if(flag==2) f[x]=(a[0]*1ll*a[1])%p*C(s[0]+s[1],s[0])%p;
}
void solve(){
    format();n=read();
    for(int i=1;i<=n;i++){
        int num=read(),lst=i;
        for(int j=1;j<=num;j++){
            int x=read();
            ins(lst,x);ins(x,lst);
            lst=x;
        }
    }dfs(1,0);
    printf("%lld\n",f[1]);
}
signed main(){
    int t=read();fac[1]=1;
    for(int i=2;i<=1000;i++) fac[i]=(fac[i-1]*1ll*i)%p;
    while(t--) solve();
    return 0;
}

T3

창고
(warehouse.cpp 1 초 256M)
야옹 은하는 n 개의 행성, 별과 행성의 나무의 형성 사이의 경로가 있습니다.
유성 B에 행성이 [DIS (a, b)이 Xor 얻어 M] 초. DIS (개 (A, B) 경로 AB의 길이를 나타낸다 XOR을 배타적 OR 연산 비트)
웨어 하우스 위치시키기 위해, PF 제가 (1 <= I는 = <지구를 생각해 N)를 다른 행성 보내고 그리고 시간.
입력
첫번째 라인은 N M. 두 양의 정수를 포함
다음으로, n-1 개의 선, 각 라인은 세 개의 양의 정수 A, B, C가하는 나타내고, B는 상기 경로 (C)의 길이이다.
N <= 100000 M <= 15 ^ 10 답변 9 * 2를 초과하지 않는
출력
행성 시간 소요와 모든 다른 행성을 나타내는 I 정수의 N-라인.
입력 샘플
. 4 0
. 1 2. 1
. (1) (2) (3)
. (1) 제 3
샘플 출력
. 6
. 8
(10)
12 인

해결책:

의 XOR 연산은 매우 간단 제거 XOR 후 어떻게 추가하는 것을 고려

우리는 그가 네 개의 진 이후에 영향을 미치는 것을 의미 15m의 최대 값이, 우리는 그 시점에서 시작하는 것이 발견

세트 \ (g는 [X] [J ] \) 로 표시 \ (X는 \) 하는 루트로하는 서브 트리이며 (X \) \ 간격 \ (MOD \ 16 \)를 같은 후 \ (J \) 포인트 번호 \ (F [X] [J]를 \) 의 모든 포인트가 것을 나타낸다 \ (X \)

그러면 운영자는 멀티 연산자 각 지점의 값에 응답하고 각각의 그의 거리에, 다른 포인트에 대한 포인트를 뺀

암호:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+1;
int n,m,cnt,sum,head[N],val[N];
int sz[N],f[N][16],g[N][16];
struct Edge{int nxt,to,val;}edge[N<<1];
void ins(int x,int y,int z){
    edge[++cnt].nxt=head[x];
    edge[cnt].to=y;head[x]=cnt;
    edge[cnt].val=z;
}
void dfs1(int x,int fa,int dis){
    sz[x]=1;sum+=dis;g[x][0]=1;
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(y==fa) continue;
        dfs1(y,x,dis+edge[i].val);
        sz[x]+=sz[y];
        for(int j=0;j<16;j++)
            g[x][(j+edge[i].val)%16]+=g[y][j];
    }
}
void dfs2(int x,int fa,int v){
    val[x]=v;
    for(int j=0;j<16;j++) f[x][j]+=g[x][j];
    for(int i=head[x];i;i=edge[i].nxt){
        int y=edge[i].to;
        if(y==fa) continue;
        for(int j=0;j<16;j++)
            f[y][(j+edge[i].val)%16]+=f[x][j]-g[y][((j-edge[i].val)%16+16)%16];
        dfs2(y,x,v+edge[i].val*1LL*(sz[1]-sz[y]-sz[y]));
    }
}
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    return x*f;
}
signed main(){
    n=read(),m=read();
    for(int i=1;i<n;i++){
        int x=read(),y=read(),z=read();
        ins(x,y,z),ins(y,x,z);
    }
    dfs1(1,0,0);
    dfs2(1,0,sum);
    for(int i=1;i<=n;i++){
        int ans=val[i];
        for(int j=0;j<16;j++)
            ans+=f[i][j]*1ll*((j^m)-j);
        printf("%lld\n",ans-m);
    }
    return 0;
}

추천

출처www.cnblogs.com/NLDQY/p/11492640.html