2019.10.11考試報告node
時間安排:ios
T1:1.5h數組
T2:1h緩存
T3:0.5hide
考場思路:spa
T1:一開始的時候想用線段樹作,而後線段樹寫炸了,在一個單點修改上出現了問題,改用暴力作,時間複雜度O(n*q),,得了四十分code
T2:一開始想用Floyd作,發現數據範圍太大了,改爲用拓撲排序來作blog
T3:原本想拿個十分的部分分,發現十分的部分分也不會寫排序
答題狀況:隊列
T1:50
T2:64
T3:0
題目分析:
T1:題目上寫的線段樹,可實際上和線段樹一點關係也沒有,就是用一個數組儲存操做3的次數,而後在每次進行操做一、2的時候,先進行一次判斷,若是小於操做的次數,那就先把這個數改爲最近的一次操做3的值後再進行處理,若是等於,那麼就說明已經處理過,就直接處理就行了,時間複雜度:O(q)
T2:拓撲排序,數據範圍太大,fFloyd,dij,spfa都會超時,因此咱們就要想另外的方法,根據題目的要求,求一個最長路,那麼該圖必定是一個有向無環圖,(若是有環,那麼最長路就是+∞了)。有向無環圖又叫拓撲圖,可用拓撲排序+DP作。而後就打一個拓撲排序+DP就行了
T3:一條鏈的狀況:當爲一條鏈時,最大值必定是兩個端點之一,最小值必定在某一個點上。指望得分:10分
正解:
T1:
#include<iostream> #include<cstdio> #include<cstring> #include<map> #include<ctype.h> #define int long long int using namespace std; const int MAXSIZE=50000020; //讀入緩存大小,不要改動 int bufpos; char buf[MAXSIZE]; int read(){ //讀入一個int類型的整數 int val = 0; for(; buf[bufpos] < '0' || buf[bufpos] > '9'; bufpos ++); for(; buf[bufpos] >= '0' && buf[bufpos] <= '9'; bufpos ++) val = val * 10 + buf[bufpos] - '0'; return val; } int a[10000010]; int b[10000010]; int ans; int tag,lazy; signed main() { freopen("segmenttree.in","r",stdin); freopen("segmenttree.out","w",stdout); buf[fread(buf, 1, MAXSIZE, stdin)] = '\0'; bufpos = 0; int n,m; n=read(); m=read(); for(int i=1;i<=m;i++) { int t; t=read(); if(t==1) { int x,y; x=read(); y=read(); if(b[x]<tag) { a[x]=lazy; b[x]=tag; } ans-=a[x]; a[x]=y; ans+=y; } if(t==2) { int x,y; x=read(); y=read(); if(b[x]<tag) { a[x]=lazy; b[x]=tag; } a[x]+=y; ans+=y; } if(t==3) { int y; y=read(); tag++; lazy=y; ans=n*y; } cout<<ans<<endl; } return 0; }
T2:
#include<iostream> #include<cstdio> #include<cstring> #include<ctype.h> #include<queue> #define int long long int using namespace std; int n,m; const int MAXSIZE=50000020; //讀入緩存大小,不要改動 int bufpos; char buf[MAXSIZE]; int read(){ //讀入一個int類型的整數 int val = 0; for(; buf[bufpos] < '0' || buf[bufpos] > '9'; bufpos ++); for(; buf[bufpos] >= '0' && buf[bufpos] <= '9'; bufpos ++) val = val * 10 + buf[bufpos] - '0'; return val; } queue <int> q; int value[1000001]; struct node { int u; int v; int w; int next; }data[1000001]; int head[1000001]; int cnt; int fl[1000001]; void add(int u,int v,int w) { cnt++; data[cnt].v=v; data[cnt].w=w; data[cnt].next=head[u]; head[u]=cnt; }//建圖 signed main() { freopen("lpsa.in","r",stdin); freopen("lpsa.out","w",stdout); buf[fread(buf, 1, MAXSIZE, stdin)] = '\0'; bufpos = 0; n=read(); m=read(); for(int i=1;i<=m;i++) { int u,v,w; u=read(); v=read(); w=read(); add(u,v,w); fl[v]++; } for(int i=1;i<=n;i++) { if(fl[i]==0) { q.push(i);//若是當前點入度爲零 ,就放入隊列中 } } while(!q.empty()) { int x=q.front(); q.pop(); for(int i=head[x];i;i=data[i].next)//從入度爲零的點開始找 { if(value[data[i].v]<value[x]+data[i].w)//由於求最長路,因此到data[i].v的距離是 value[data[i].v] 和 data[i].w+value[x] 的最大值 { value[data[i].v]=value[x]+data[i].w; } fl[data[i].v]--;//入度減一 if(fl[data[i].v]==0)//入度爲零 { q.push(data[i].v); } } } int ans=0; for(int i=1;i<=n;i++) { ans=max(ans,value[i]); } cout<<ans<<endl; return 0; }
T3:懵逼ing。。。