codeforces702E---倍增法求解,第一发

来源:互联网 发布:软媒魔方怎么优化图标 编辑:程序博客网 时间:2024/06/15 15:24

倍增法是著名的RMQ算法的思想基础。其中的倍增是为了得到二进制数字,。这样我们需要一个k的长度的数值,就是需要k的二进制的一些组合,同时,由于lgn的内存和lgn的搜索速度,都是可以接受的,同时2^N--->2^(N+1)可以通过维护转移来得到,也就是DP,这样就是一个完美无缺的解法,同时,如果可以适用于许多的问题。

上代码:

#include <algorithm>#include <assert.h>#include <complex>#include <ctype.h>#include <functional>#include <iostream>#include <limits.h>#include <locale.h>#include <map>#include <math.h>#include <queue>#include <set>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <string>#include <time.h>#include <vector>//#include <unordered_set>//#include <unordered_map>#pragma warning(disable:4996)using namespace std;#define mp make_pairtypedef long long ll;typedef unsigned long long ull;typedef double db;typedef long double ldb;typedef pair <int, int> pii;typedef pair <ll, ll> pll;typedef pair <ll, int> pli;typedef pair <ldb, ldb> pdd;int IT_MAX = 1 << 21;const int MOD = 1000000007;const int INF = 1034567891;const ll LL_INF = 1234567890123456789ll;const db PI = 3.141592653589793238;const ldb ERR = 1E-12;vector <int> h[100010] ;int gra[100010] ;int weg[100010] ;int vis[100010] ;int d[100010][60] ;ll sum[100010][60] ; /// 表示长度是2^n的i开始的最终的sum和ll mam[100010][60] ; /// 表示长度是2^n的i开始的最终的max和int cnt = 0 ;#define mem(x ,y ) memset(x , y , sizeof(x))int main() {    ll n , m ;cin >> n >> m ;    for(int i=0;i<n;i++){        scanf("%d" ,gra+i) ;    }    for(int i=0;i<n;i++) scanf("%d" ,  weg+i) ;    for(int i=0;i<n;i++){        d[i][0]   = gra[i] ;        sum[i][0] = weg[i] ;        mam[i][0] = weg[i] ;    }    for(int i=1;i<60;i++){        for(int j=0;j<n;j++){            int tmp = d[j][i-1] ;            d[j][i] = d[tmp][i-1] ;            sum[j][i] = sum[j][i-1] + sum[tmp][i-1] ;            mam[j][i] = min(mam[j][i-1] , mam[tmp][i-1]) ;        }    }    for(int i=0;i<n;i++){        ll k = m ;        int tmp = i ;        int cnt = 0 ;        ll sss = 0 ;        ll mmm = LL_INF ;        while(k){            if(k & 1){                sss += sum[tmp][cnt] ;                mmm = min(mmm , mam[tmp][cnt]) ;                tmp = d[tmp][cnt] ;            }            cnt ++ ; k >>= 1 ;        }        printf("%I64d %I64d\n" , sss , mmm) ;    }}


0 0
原创粉丝点击