zoukankan      html  css  js  c++  java
  • 【SCOI2016】Day1 模拟

    2018.8.16 8:00~11:06

    先看t1,成功读错题。。。

    以为是一个字符串的所有后缀都得在计划表里,否则权值就得是$n^2$

    然后花了一个小时多一点写了一个错误的做法

    然后没有分 才发现看错了题意

    不过只要稍微改一改就行了

    在近两个小时的时候过掉了第一题

    然后看t2,显然的线性基+树剖,复杂度$O(n log n imes 60 + q log ^2 n imes 60)$

    看了一下不知道能拿多少分 但是想不到更好的做法 于是就写了

    获得了90分 真是不可思议

    t3花了10分钟敲了一个30分暴力

    总分:100+90+30

    总结

    感觉这一场打的没什么问题了吧

    难得啊

    题解

    T1「SCOI2016」背单词

    题面:

    https://loj.ac/problem/2012

    题解:

    首先把所有字符串倒过来,把后缀变成前缀

    然后建立trie树

    显然的有一个性质:对于trie树上的一个结点来说,他在最终排列中的位置一定在他的所有祖先之后,所有儿子之前

    因为如果不这样,出现了祖先->儿子->自己的情况,我们把儿子自己调换位置,答案变优

    然后考虑一个结点的子树

    不难发现子树内部的结点一定靠在一起

    因为如果不靠在一起,比如说儿子1->儿子2->儿子1的儿子1->儿子2的儿子1

    我们把儿子2儿子1的儿子1调换位置,儿子1的儿子1儿子2的儿子1代价都减小

    所以一个子树内部的结点靠在一起

    最后我们确定子树之间的顺序

    现在子树唯一有用的就是他的size

    我们把子树设为$1~x$

    最后的顺序设为$p_1~p_x$

    cost就是$(1)+(1+size_{p_1})+(1+size_{p_1}+size_{p_2})+...+(1+size_{p_1}+size_{p_2}+...+size_{p_{x-1}})$

    这样我们看出 应该将size按照升序排列最优

    所以我们的做法就是:建立trie树,然后dfs一遍把无效结点去掉(就是那些不是终止结点的点),然后建立一个新的树(压缩之后的trie),dfs找到size,并通过size计算出每个结点的cost值(树形dp),最后dp[1]就是答案

    Code:

      1 #include<stdio.h>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<vector>
      6 #include<map>
      7 #include<set>
      8 #include<cmath>
      9 #include<iostream>
     10 #include<queue>
     11 #include<string>
     12 using namespace std;
     13 typedef long long ll;
     14 typedef pair<int,int> pii;
     15 typedef long double ld;
     16 typedef unsigned long long ull;
     17 typedef pair<long long,long long> pll;
     18 #define fi first
     19 #define se second
     20 #define pb push_back
     21 #define mp make_pair
     22 #define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
     23 #define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)
     24 
     25 ll read(){
     26     ll x=0,f=1;char c=getchar();
     27     while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
     28     while(c>='0' && c<='9'){x=x*10+c-'0';c=getchar();}
     29     return x*f;
     30 }
     31 
     32 int n;
     33 string s[100100];
     34 
     35 struct TRIE{
     36     int cnt;
     37     int pos[520000][26];
     38     int tag[520000];
     39     vector<int> adj[520000];
     40     ll dp[520000],sz[520000];
     41     
     42     TRIE(){
     43         cnt=1;
     44     }
     45     
     46     void ins(string t,int ind){
     47         int pp=1;
     48         for(int i=0;i<t.size();i++){
     49             int nw=t[i]-'a';
     50             if(pos[pp][nw]) pp=pos[pp][nw];
     51             else{
     52                 cnt++;
     53                 pos[pp][nw]=cnt;
     54                 pp=cnt;
     55             }
     56         }
     57         tag[pp]=ind;
     58     }
     59     
     60     void dfs(int u,int fa=1){
     61         if(tag[u] && u!=fa) adj[fa].pb(u);
     62         for(int i=0;i<26;i++){
     63             int nw=pos[u][i];
     64             if(nw==0) continue;
     65             if(tag[u]) dfs(nw,u);
     66             else dfs(nw,fa);
     67         }
     68     }
     69     
     70     void work(int u){
     71         vector<int> nw;
     72         sz[u]=1;
     73         for(int i=0;i<adj[u].size();i++){
     74             int v=adj[u][i];
     75             work(v);
     76             nw.pb(sz[v]);
     77             sz[u]+=sz[v];
     78             dp[u]+=dp[v];
     79         }
     80         sort(nw.begin(),nw.end());
     81         ll sum=1;
     82         for(int i=0;i<nw.size();i++){
     83             dp[u]+=sum;
     84             sum+=nw[i];
     85         //    cout<<nw[i]<<' ';
     86         }
     87         //cout<<endl;
     88     }
     89     
     90     void calc(){
     91         work(1);
     92         cout<<dp[1]<<endl;
     93     }
     94 } trie;
     95 
     96 int main(){
     97 //    freopen("out","w",stdout);
     98     n=read();
     99     rep(i,1,n){
    100         cin>>s[i];
    101         reverse(s[i].begin(),s[i].end());
    102         trie.ins(s[i],i);
    103     }
    104     
    105     trie.dfs(1);
    106     trie.calc();
    107     
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    TP5 自带封装分页查询
    TP5 接口 前面拼接 当前域名
    button按钮点击后过段时间不能点击-验证码(刷新后失效)
    关于PHP -session 的 A session had already been started – ignoring session_start() 错误
    301 Moved Permanently
    PHP实现远程下载图片与 图片接口定义
    在TP框架的前端中 想引用 PHP的函数
    流程控制语句2
    流程控制语句
    数据库查询数据2
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9486450.html
Copyright © 2011-2022 走看看