VK Cup 2018 Round 1 and CF Round #470 div2 C


首先附上题目的原链接、http://codeforces.com/contest/948/problem/C、方便自己以后的复习、

先讲讲自己的的思路吧、一开始我就崇尚暴力、直接用两个for循环遍历总的天数、以及每一天经受接下来温度的考验


在这里贴上自己的代码、

    static final int MAXN = 100005;
    static int [] a = new int [MAXN]; // 存的每一天堆得雪的数量、、
    static int [] aa = new int [MAXN]; // 存的每一天堆得雪的数量、、
    static int [] b = new int[MAXN]; //  存的每一天的温度、、
    static long [] restore = new long [MAXN];
    static int N;
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken();  N = (int)in.nval;
        for(int i = 0; i < N; i++){
            in.nextToken(); aa[i] = a[i] = (int)in.nval;
        }
        int tmp;
        for(int i = 0; i < N; i++){
            in.nextToken(); b[i] = (int)in.nval;
        }
        
        long res = 0;
        for(int i = 0; i < N; i++){ // 遍历每一天的温度、、
            res = 0;
            tmp = a[i]; // 当天开始前的雪的数量、、
            for(int j = 0; j <= i; j++){
                res += (a[j] - b[i]) >= 0 ? b[i] : a[j];
                a[j] = (a[j] - b[i]) >= 0 ? a[j] - b[i] : 0;  // 剩余的雪的数量 是正确的、、
            }

            if(i != N - 1){
                out.print(res + " ");
            }else{
                out.println(res);
            }
            out.flush();
        }
        
    }

很无情似的、cf给我报超时了、因为自己还是蛮菜的、然后比赛结束后、自己写了写、线段树解决的代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;    

public class C {
    static final int MAXN = 100005;
    static long [] v = new long [MAXN];
    static long [] t = new long [MAXN];
    static long [] to = new long [MAXN];
    static long [] ans = new long[MAXN];
    static long [] c = new long[MAXN];
    static int N;
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        in.nextToken(); N = (int)in.nval;
        for(int i = 1; i <= N; i++){
            in.nextToken(); v[i] = (long)in.nval;
        }
        for(int i = 1; i <= N; i++){
            in.nextToken(); t[i] = (long)in.nval;
            to[i] += t[i] + to[i - 1];
        }
        for(int i = 1; i <= N; i++){
            long tp = v[i] + to[i - 1];
            int pos = lower(tp);  // 二分查找当前雪能存活到的最后一天、、
            if(i < pos){  // 这几天每天都会融化雪、、
                update(i, 1);
                update(pos, -1); // 这个之后雪就消失了、 更新减去见面增加的、、
            }
            if(i <= pos){
                if(tp > to[pos]){
                    ans[pos] += t[pos];  // 当天的温度不足以融化 雪还有剩余、、
                }else{
                    ans[pos] += v[i] + to[i - 1] -to[pos - 1]; // 当天融化直接消失、、那增加的就是最小前一天剩余的咯、而不是当天的温度
                }
            }
        }
        
        for(int i = 1; i <= N; i++){
            ans[i] += t[i] * query(i);
        }
        for(int i = 1; i <= N; i++){
            if(i != N){
                out.print(ans[i] + " ");
            }else{
                out.println(ans[i]);
            }
        }
        out.flush();
    }
    
    
    private static void update(int pos, int val){
        while(pos <= N){
            c[pos] += val;
            pos += (pos & - pos);
        }
    }
    
    private static int query(int pos){
        int ret = 0;
        while(pos > 0){
            ret += c[pos];
            pos -= (pos & - pos);
        }
        return ret;
    }
    
    private static int lower(long x){
        int l = 1, r = N, mid;
        while(l < r){
            mid = l + ((r - l)>> 1);  // 注意优先级、、 避免 l + r  直接爆了(超过数据 超过int的范围)
//            mid = (l + r) >> 1;
//            System.out.println("l = " + l + " r = " + r);
            if(to[mid] >= x) r = mid;
            else l = mid + 1;
        }
        return l;
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值