JSOI2018真题感悟

D1T1潜入行动:

大水题,可是本菜鸡手一抖MLE了,GG

#include<iostream>
#include<cstdio>
#define llint long long int
using namespace std;

const llint maxn = 200005;
const llint maxk = 107;
const llint modd = 1e9+7;
llint n, k;

struct atree {//choose safe
    int dp[100005][maxk][2][2];
    llint st[maxn], to[maxn], nx[maxn], tm, up[maxn], tt;
    void adde(llint aa, llint bb) {
        tm++;
        nx[tm]=st[aa];
        to[tm]=bb;
        st[aa]=tm;
        return;
    }
    void count(llint x, llint fa) {
        //cout<<x<<endl;
        llint i, y, j, p, tt, t[2][2];
        dp[x][0][0][0]=1;
        dp[x][1][1][0]=1;
        up[x]=1;
        for(i=st[x]; i != 0; i=nx[i]) {
            y=to[i];
            if(y == fa) continue;
            count(y, x);
            for(j=up[x]; j >= 0; j--) {
                t[0][0]=dp[x][j][0][0];
                t[0][1]=dp[x][j][0][1];
                t[1][0]=dp[x][j][1][0];
                t[1][1]=dp[x][j][1][1];
                dp[x][j][0][0]=dp[x][j][0][1]=dp[x][j][1][0]=dp[x][j][1][1]=0;
                for(p=min(up[y], k-j); p >= 0; p--) {
                    up[x]=max(up[x], j+p);

                    tt=dp[x][j+p][0][0];
                    tt+=t[0][0]*dp[y][p][0][1]%modd;
                    tt%=modd;
                    dp[x][j+p][0][0]=tt;

                    tt=dp[x][j+p][0][1];
                    tt+=t[0][0]*dp[y][p][1][1]%modd;
                    tt+=t[0][1]*dp[y][p][0][1]%modd;
                    tt+=t[0][1]*dp[y][p][1][1]%modd;
                    tt%=modd;
                    dp[x][j+p][0][1]=tt;

                    tt=dp[x][j+p][1][0];
                    tt+=t[1][0]*dp[y][p][0][1]%modd;
                    tt+=t[1][0]*dp[y][p][0][0]%modd;
                    tt%=modd;
                    dp[x][j+p][1][0]=tt;

                    tt=dp[x][j+p][1][1];
                    tt+=t[1][0]*dp[y][p][1][1]%modd;
                    tt+=t[1][0]*dp[y][p][1][0]%modd;
                    tt+=t[1][1]*dp[y][p][0][0]%modd;
                    tt+=t[1][1]*dp[y][p][0][1]%modd;
                    tt+=t[1][1]*dp[y][p][1][0]%modd;
                    tt+=t[1][1]*dp[y][p][1][1]%modd;
                    tt%=modd;
                    dp[x][j+p][1][1]=tt;
                }
            }
        }
        return;
    }
} T;

int main() {
    llint i, ta, tb, tt;
    cin>>n>>k;
    for(i=1; i < n; i++) {
        cin>>ta>>tb;
        T.adde(ta, tb);
        T.adde(tb, ta);
    }
    T.count(1, 0);
    tt=T.dp[1][k][0][1]*1ll+T.dp[1][k][1][1]*1ll;
    cout<<((tt)%modd+modd)%modd<<endl;
}


D2T3列队:

蛮水的吧,可是我Naive地认为卡卡常直接二分能过

卡了很久以后才想起来写主席树上二分.

loj稳过,luogu迷之TLE

#include<iostream>
#include<cstdio>
#define llint long long int
using namespace std;

const llint maxn = 20000005;
llint mp;
llint a[maxn];

struct atree {
    llint num[maxn];
    int tn, st[maxn], ls[maxn], rs[maxn], tm;
    void build(int x, int l, int r) {
        num[x]=0;
        if(l == r) return;
        int mid=(l+r)/2;
        tm++; ls[x]=tm; build(ls[x], l, mid);
        tm++; rs[x]=tm; build(rs[x], mid+1, r);
        return;
    }
    void add_do(int x1, int x2, int l, int r, int p1, llint num1) {
        if(l == r) {num[x1]=num[x2]+num1; return;}
        int mid=(l+r)/2;
        if(p1 <= mid) {
            tm++; ls[x1]=tm; rs[x1]=rs[x2];
            add_do(ls[x1], ls[x2], l, mid, p1, num1);
        }
        else {
            tm++; rs[x1]=tm; ls[x1]=ls[x2];
            add_do(rs[x1], rs[x2], mid+1, r, p1, num1);
        }
        num[x1]=num[ls[x1]]+num[rs[x1]];
        return;
    }
    inline void add(int p1, llint num1) {
        tn++; tm++; st[tn]=tm;
        add_do(st[tn], st[tn-1], 0, mp, p1, num1);
    }
    llint ask_do(int x1, int x2, int l, int r, int pl, int pr) {
        if(r < pl || pr < l) return 0;
        if(num[x2]-num[x1] == 0) return 0;
        if(pl <= l && r <= pr) return num[x2]-num[x1];
        int mid=(l+r)/2;
        llint anst;
        anst=
        ask_do(ls[x1], ls[x2], l, mid, pl, pr) +
        ask_do(rs[x1], rs[x2], mid+1, r, pl, pr);
        return anst;
    }
    inline llint ask(int b1, int b2, int pl, int pr) {
        if(pr > mp) pr=mp;
        if(pl > pr) return 0;
        return ask_do(st[b1-1], st[b2], 0, mp, pl, pr);
    }
    llint find_it(int x1, int x2, int l, int r, llint tk) {
        if(r == l) return l;
        int mid=(l+r)/2;
        if(num[ls[x2]]-num[ls[x1]] > (mid-tk+1))
            return find_it(rs[x1], rs[x2], mid+1, r, tk+num[ls[x2]]-num[ls[x1]]);
        else return find_it(ls[x1], ls[x2], l, mid, tk);
    }
    inline llint find(int b1, int b2, llint tk) {
        return find_it(st[b1-1], st[b2], 0, mp, tk);
    }
} T1, T2;

inline llint csum(llint l, llint r) {
    if(l > r) return 0;
    return (l+r)*(r-l+1ll)/2ll;
}

inline llint read(){
   llint s=0,w=1;
   char ch=getchar();
   while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)w=-1;ch=getchar();}
   while(ch>=‘0‘&&ch<=‘9‘) s=s*10+ch-‘0‘,ch=getchar();
   return s*w;
}
inline void write( llint x ) {
    char F[2000] ;
    if(x == 0) putchar(‘0‘);
    llint tmp = x > 0 ? x : -x ;
    if( x < 0 ) putchar( ‘-‘ ) ;
    int cnt = 0 ;
       while( tmp > 0 ) {
           F[ cnt ++ ] = tmp % 10 + ‘0‘ ;
           tmp /= 10 ;
       }
       while( cnt > 0 ) putchar( F[ -- cnt ] ) ;
}
int main() {
    //freopen("line.in", "r", stdin);
    //freopen("line.out", "w", stdout);
    T1.tm=1; T1.tn=0; T1.st[0]=1;
    T2.tm=1; T2.tn=0; T2.st[0]=1;
    llint i, ta, tb, tk, ans, ansp, n, m;
    n=read(), m=read();
    for(i=1; i <= n; i++) {
        a[i]=read();
    }
    mp=1000005;
    T2.build(1, 0, mp);
    T1.build(1, 0, mp);
    //cout<<T1.tm<<endl;
    for(i=1; i <= n; ++i) {
        T1.add(a[i], 1);
        T2.add(a[i], a[i]);
    }

    for(i=1; i <= m; ++i) {
        ta=read();
        tb=read();
        tk=read();
        ans=0;
        ansp=T1.find(ta, tb, tk);
        if(ansp == 1000005) ansp=tk+tb-ta;
        ans+=csum(tk, ansp)-T2.ask(ta, tb, 1, ansp);
        ans+=T2.ask(ta, tb, ansp+1, mp)-csum(ansp+1, tk+tb-ta);
        write(ans);
        putchar(‘\n‘);
    }
    return 0;
}


D1T3绝地反击:

想出来爬山+二分了,结果没敢想网络流

不行,我还是Too Young,Too Simple



JSOI2018真题感悟

原文地址:https://www.cnblogs.com/crraphael/p/11562962.html

时间: 2024-11-10 08:22:47

JSOI2018真题感悟的相关文章

拼多多后台开发面试真题:如何用Redis统计独立用户访问量

众所周至,拼多多的待遇也是高的可怕,在挖人方面也是不遗余力,对于一些工作3年的开发,稍微优秀一点的,都给到30K的Offer,当然,拼多多加班也是出名的,一周上6天班是常态,每天工作时间基本都是超过12个小时,也是相当辛苦的.废话不多说,今天我们来聊一聊拼多多的一道后台面试真题,是一道简单的架构类的题目:拼多多有数亿的用户,那么对于某个网页,怎么使用Redis来统计一个网站的用户访问数呢? 使用Hash 哈希是Redis的一种基础数据结构,Redis底层维护的是一个开散列,会把不同的key映射到

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh童鞋的提醒. 勘误2:第7题在推断连通的时候条件写错了,后两个if条件中是应该是<=12 落了一个等于号.正确答案应为116. 1.煤球数目 有一堆煤球.堆成三角棱锥形.详细: 第一层放1个, 第二层3个(排列成三角形), 第三层6个(排列成三角形), 第四层10个(排列成三角形). -. 假设一共

程序设计语言基本概念语 与经典真题

一.基本概念 在计算机中,程序设计语言可划分为低级语言和高级语言两大类,与高级语言相比,用低级语言开发的程序,其运行效率高,但开发效率低.与程序设计相关的基本概念如下. (1)低级语言:又称面向机器语言,它是特定的计算机系统所固有的语言. (2)汇编语言:是机器语言的一种提升,它使用了一些助记符来表示机器指令中的操作码和操作数.但它仍然是一种和计算机机器语言十分接近的语言,使用起来仍然不太方便. (3)高级语言:与人们的自然语言比较接近,使用起来很方便,也极大的提高了程序设计效率. (4)编译程

[华为机试真题]66.单词搜索

题目 代码 /*--------------------------------------- * 日期:2015-07-06 * 作者:SJF0115 * 题目:WordSearch * 来源:华为机试真题 -----------------------------------------*/ #include <iostream> #include <string> #include <vector> #include <stack> #include

九度oj 1034 寻找大富翁 2009年浙江大学计算机及软件工程研究生机试真题

题目1034:寻找大富翁 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5323 解决:2123 题目描述:     浙江桐乡乌镇共有n个人,请找出该镇上的前m个大富翁. 输入:     输入包含多组测试用例.    每个用例首先包含2个整数n(0<n<=100000)和m(0<m<=10),其中: n为镇上的人数,m为需要找出的大富翁数, 接下来一行输入镇上n个人的财富值.    n和m同时为0时表示输入结束. 输出:     请输出乌镇前m个大富翁的财产数,财产多的

九度oj 1464 Hello World for U 2012年浙江大学计算机及软件工程研究生机试真题

题目1464:Hello World for U 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:3872 解决:1082 题目描述: Given any string of N (>=5) characters, you are asked to form the characters into the shape of U. For example, "helloworld" can be printed as: h    de     ll      rlowo

蓝桥杯——真题训练之蚂蚁感冒

标题:蚂蚁感冒 长100厘米的细长直杆子上有n只蚂蚁.它们的头有的朝左,有的朝右. 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒. 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行. 这些蚂蚁中,有1只蚂蚁感冒了.并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁. 请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒. [数据格式] 第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数. 接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100),

蓝桥杯——历年真题之带分数

问题描述 100 可以表示为带分数的形式:100 = 3 + 69258 / 714. 还可以表示为:100 = 82 + 3546 / 197. 注意特征:带分数中,数字1~9分别出现且只出现一次(不包含0). 类似这样的带分数,100 有 11 种表示法. 输入格式 从标准输入读入一个正整数N (N<1000*1000) 输出格式 程序输出该数字用数码1~9不重复不遗漏地组成带分数表示的全部种数. 注意:不要求输出每个表示,只统计有多少表示法! 样例输入1 100 样例输出1 11 样例输入

九度机试 题目1165:字符串匹配 2008年北京航空航天大学计算机研究生机试真题

题目1165:字符串匹配 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2497 解决:858 题目描述: 读入数据string[ ],然后读入一个短字符串.要求查找string[ ]中和短字符串的所有匹配,输出行号.匹配字符串.匹配时不区分大小写,并且可以有一个用中括号表示的模式匹配.如"aa[123]bb",就是说aa1bb.aa2bb.aa3bb都算匹配. 输入: 输入有多组数据. 每组数据第一行输入n(1<=n<=1000),从第二行开始输入n个字符串(