玲瓏杯」ACM比賽 Round 11 待補

2021-07-28 00:08:00 字數 3772 閱讀 4456

題目:

官方題解:

直接貼上了,沒過的題以後再補(儘管不太可能qaq)

第一題、直接列舉所有可能的x並且計算答案,得出最優解

【水題,忽略】

第二題、可以連線的兩個工廠相當於可以匹配的兩個點,那麼問題轉化為求兩個串的最長公共子串行,但o(n^2)的複雜度會超時,由於第二個串每個點最多只有6個點與之匹配,所以可以把第二個串的每個點變成可以與之匹配的六個編號從大到小排序,然後求最長上公升子串行。

【這種套路題還是見過些的】

#include

using

namespace

std;

typedef

long

long ll;

const

int n=1e6+9;

const

int inf=1e9+7;

int g[n],d[n],a[n],k[11];

int n;

int main()

sort(k,k+6);

for(int j=5;j>=0;j--)a[cnt++]=k[j];

}for(int i=1;i<=cnt;i++)g[i]=inf;

for(int i=0;iint k=lower_bound(g+1,g+n+1,a[i])-g;

d[i]=k;

g[k]=a[i];

ans=max(ans,d[i]);

}cout

0;}

第三題、當一課排序二叉樹建立起來之後我們可以發現,從某個點x往上走,第乙個往左的節點的值是在x前插入的小於x的最大值,第乙個往右的值是在x前插入的大於x的最小值,所以x所在的層數就是在插入x之前比x大的最小值的層數和比x小的最大值的層數中,較大值加一,若把問題反過來看,不是插入而是從二叉樹中把乙個個點拿走,那麼可以很簡單地用並查集找到上述的兩個值。

【講真,這題挺不錯的(雖然沒做出來),還是可以做的】

第四題、由於x經過一次函式呼叫f(x)之後不超過9^3,所以直接找迴圈節即可。

【水題略過】

第五題、先對原串st做一次kmp,然後做動態規劃f[i][j]表示長度為i的字串中不存在子串為st並且所有字尾中與st的字首匹配的最長長度為j,然後列舉第i+1位的字元,如果等於st[j+1]的話那麼轉移到f[i+1][j+1],否則轉移到f[i][k],其中k由kmp演算法計算得到。

【這題自己一開始想錯了,瘋狂wa,沒做出來qaq】

#include

using

namespace

std;

typedef

long

long ll;

const

int mod=1e9+7;

const

int n=1000+7;

char ch, s[n];

int dp[n][n], c[n][156], nex[n];

int main() else

p = nex[p];

}for(i=1; i<=m; i++)

// printf("\n");

}dp[0][0] = 1;

for(i=1; i<=n; i++)

}ans = 0;

for(i=0; i<=m-1; i++)

ans = (ans+dp[n][i])%mod;

printf("%d\n", ans);

}return

0;}

第六題、只要判斷兩個:1、所有對角線連線的端點顏色都不一樣;2、所有線段都不想交。

【哇~~,題解好簡單啊(一開始沒看到相鄰兩點顏色不同,還想了好一會兒 t_t)】

第七題、我們先計算出tornado的速度為v0,然後分類討論:1、如果v > v0那麼肯定可以追上;2、如果v == v0,那麼速度向量與(x1-x0, y1-y0)的夾角小於90度就可以追上;3、我們先假設可以追上,而且時間為t,那麼追上時tornado走過的路程長度為t v0,feigay走過的路程為t v,加上tornado和feigay原始位置的距離,還有速度向量和(x1-x0, y1-y0)的夾角可以根據餘弦定理列出方程,若有正數解那麼可以追上。

【題解講的很清楚了,分情況討論即可】

第八題、可以先想到乙個dp的方法f[i][j] = max。可是這個dp是o(n^2)時間複雜度的,我們可以觀察轉移方程,發現求最大值的k其實是一段連續的值,所以可以利用選段樹或者樹狀陣列進行優化,把複雜度降低成o(m * log n)。

【沒想過dp,一上來直接考慮樹狀陣列啊】

#include

using

namespace

std;

#define fi first

#define se second

typedef pairpii;

typedef

long

long ll;

const

int inf=0x3f3f3f3f;

const

int n=3000000+7;

ll c[n],a[n],b[n];

pii e[n];

int cmp(const pii& a,const pii& b)

void add(int x,ll v)

int main()

for(int i=1;i<=n;i++)scanf("%lld",&a[i]);

for(int i=1;i<=n;i++)scanf("%lld",&b[i]);

sort(e,e+m,cmp);

for(int i=0;iint u=e[i].fi,v=e[i].se;

ll t=query(v-1);

add(v,t+a[u]+b[v]);

}printf("%lld\n",query(n));

}return

0;}

第九題、如果n大於6的時候結果肯定為0,因為每次a與b操作之後至少可以使a的1的數量減少一半,所以進行6次操作肯定可以使a變成0。當n小於等於6的時候,暴力列舉每個數是否取反以及每個數之間的符號。

【看完題解恍然大悟啊qaq,因為a和b或者~b相與,至少可以使a的數量減少一半,那麼進行6次以上肯定是0了。相與6直接暴力。另外,其實或,異或沒啥用(或是真的沒用,異或可以用~和&代替】

#include

using

namespace

std;

typedef

unsigned

long

long ll;

const

int n=1e6+9;

const

int inf=1e9+7;

ll a[n], ans;

int n;

void dfs(int x, ll now)

dfs(x+1, now & a[x]);

dfs(x+1, now & ~a[x]);

}int main()

if (n > 6) else

}return

0;}

第十題、先求出樹的dfs序,進入乙個點以及離開乙個點都在dfs序上有乙個標記,然後每一條鏈和子樹上的操作都可以變成dfs序上的一段區間,把dfs序做成兩棵線段樹,黑白各一棵,黑點在白樹上值為0,白點在黑樹上值為0,進入點的值為正數,離開點的值為負數,那麼對於乙個翻轉操作就是把黑白樹對應的一段交換,打個標記就好,對於一次詢問,分成上公升和下降兩段,上公升取反跟下降的和加起來就是答案,注意最近公共祖先要特殊處理好。

【佔坑待補】

「玲瓏杯」ACM比賽 Round 23

a 生是脂肪的人 time limit 2s memory limit 128mbyte submissions 263solved 97 description 給定乙個整數n,輸出 10 n 7 的個位數。其中 abs n 1e18 input 第一行是乙個正整數t 1 t 100 表示資料組數...

暑 假 隊 測 Round 1

暑假第一次隊測就被吊起來打了。50 37 100 187pts t1國王遊戲 t2沒找到,題目大意 t3computer network t1 貪心 是個很經典的鄰項微擾,可惜不會打高精 wtcl t2 dfs n和m的資料範圍很明顯是在暗示dfs 剪枝了,我這個睿智還是碼了個01揹包。37滾粗。t...

四校省選 Round 1

題解就不寫了。但是是非常值得反思的兩場考試。完全按照省選模擬出來的兩場。最近的考試狀態一直很差勁,這兩場暴露的細節更加致命。尤其是 day2 t1 很早就讀出了題意寫了正解,對拍也打好了。結果離散化陣列沒開二倍,直接炸成10分。昨天的題 t1 也是類似的問題。推出30分的寫法,結果 bsgs 上界寫...