<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      大炮妙妙屋

      快進來,非常好玩

      Od deski do deski

      怎么說呢,確實想到了刪的區間互不交,然后就從放置整個區間去想,就假了

      考慮修繕區間,設\(dp_{i,j,0/1}\)表示當前區間不合法/合法,在后面一位放置\(j\)種數就合法了

      那就相當于有一個區間前閉后開,開的結尾有\(j\)種補全方法,就可以按照\(i + 1\)位新放的數字是\(j\)種還是剩的\(m - j\)種分討了

      然后前\(i\)位最多\(i\)種,所以是\(n^2\)

      甲苯先生的字符串

      矩陣裸題,遍歷\(s_1\)把相鄰的標記為不能走,用\(trick\)\(n - 2\)次冪,最后對矩陣求和即可

      某位歌姬的故事

      有熟人啊

      我們發現,如果一個區間被多個限制包含,設最小限制為\(minn\),那么$ > minn$的限制不影響這個區間,所以我們考慮枚舉所有限制,然后找出所有最小限制為當前枚舉值的區間來填這個數,由此做大炮

      定義\(dp_{i,j}\)表示\(i\)個區間填了當前值,最后一個填了的是\(j\),根據當前區間填不填這個值轉移即可

      更多細節
      #include<bits/stdc++.h>
      #define ll long long
      #define mod 998244353
      #define N 1005
      using namespace std;
      int T;
      ll n,q,A;
      int qj[N << 1],num;
      int l[N],r[N],maxx[N];
      int lim[N],h[N];
      int minn[N];
      int len[N],pt[N];
      int dp[N][N];
      ll qp(ll base,ll ci)
      {
      	ll res = 1;
      	while(ci)
      	{
      		if(ci & 1) res = res * base % mod;
      		base = base * base % mod;
      		ci >>= 1;
      	}
      	return res;
      }
      int main()
      {
      	cin >> T;
      	while(T--)
      	{
      		num = 0;
      		memset(l,0,sizeof(l));
      		memset(r,0,sizeof(r));
      		memset(lim,0,sizeof(lim));
      		memset(h,0,sizeof(h));
      		memset(maxx,0,sizeof(maxx));
      		memset(qj,0,sizeof(qj));
      		cin >> n >> q >> A;
      		for(int i = 1;i <= q;i++)
      		{
      			cin >> l[i] >> r[i] >> maxx[i];
      			qj[++num] = l[i] - 1;qj[++num] = r[i]; 
      		}
      		qj[++num] = 0;qj[++num] = n;
      		sort(qj + 1,qj + num + 1);
      		num = unique(qj + 1,qj + num + 1) - qj - 1;
      		for(int i = 1;i <= num;i++) lim[i] = A + 1;
      		for(int i = 1;i <= q;i++)
      		{
      			l[i] = lower_bound(qj + 1,qj + num + 1,l[i] - 1) - qj;
      			r[i] = lower_bound(qj + 1,qj + num + 1,r[i]) - qj;
      			for(int j = l[i];j < r[i];j++) lim[j] = min(lim[j],maxx[i]);
      			h[i] = maxx[i];
      		}
      		int flag = 0;
      		for(int i = 1;i <= q;i++)//如果別的區間壓制導致某一區間取不到max就無解 
      		{
      			int mx = 0;
      			for(int j = l[i];j < r[i];j++) mx = max(mx,lim[j]);
      			if(mx < maxx[i])
      			{
      				cout << 0 << endl;
      				flag = 1;
      				break;
      			} 
      		}
      		if(flag) continue;
      //		cout << "M" << endl; 
      		sort(h + 1,h + q + 1);
      		ll ans = 1;
      		for(int i = 1;i <= q;i++)
      		{
      			int pos = i;
      			while(pos < q && h[pos + 1] == h[i]) pos++;
      			memset(minn,0,sizeof(minn));
      			int tmp = 0;
      			//把與當前枚舉限制相同(lim相同)的區間提取出來 
      			for(int j = 1;j < num;j++)
      			{
      				if(lim[j] == h[i])
      				{
      					len[++tmp] = qj[j + 1] - qj[j];
      					pt[tmp] = j + 1;
      				}
      			}
      			//在原先限制的區間為當前枚舉值的區間中,找到最小限制(lim)是當前枚舉值的部分
      			//由于原先區間離散化了,所以這里要映射到離散化對應的值 
      			//這些部分是填枚舉值的部分 
      			for(int j = 1;j <= q;j++) 
      			{
      				if(maxx[j] == h[i])
      				{
      					int po = upper_bound(pt + 1,pt + tmp + 1,r[j]) - pt - 1;
      					minn[po] = max(minn[po],l[j] + 1);
      				}
      			}
      			//dp[i][j]: 填了前 i 塊,最后一個填了當前枚舉值的區間為 j 
      			for(int j = 0;j <= tmp;j++) for(int k = 0;k <= tmp;k++) dp[j][k] = 0;
      			dp[0][0] = 1;
      			for(int r = 1;r <= tmp;r++)
      			{
      				ll tot = 0;ll sum = qp(h[i] - 1,len[r]);//剩余部分隨便填 
      				for(int s = 0;s < r;s++)
      				{
      					if(!dp[r - 1][s]) continue;
      					tot = (tot + dp[r - 1][s]) % mod;
      					if(minn[r] > pt[s]) continue;//有交集就跳過 
      					//不在當前塊填,那就是[1,h[i] - 1]隨便填,就是sum 
      					dp[r][s] = (dp[r][s] + dp[r - 1][s] * sum % mod) % mod;
      				}
      				//在這里填,至少得有一個,所以減去 sum 
      				dp[r][r] = (qp(h[i],len[r]) - sum + mod) * tot % mod;
      			}
      			ll res = 0;
      			for(int j = 0;j <= tmp;j++) res = (res + dp[tmp][j]) % mod;
      			ans = (ans * res) % mod;
      			i = pos;
      		} 
      		for(int i = 1;i < num;i++) if(lim[i] == A + 1) ans = ans * qp(A,qj[i + 1] - qj[i]) % mod;
      		cout << ans << endl;
      	}
      	return 0;
      }
      

      Permutation Oddness

      逆天轉化建議去看第二篇題解

      潛入行動

      \(dp_{x,i,0/1,0/1}\)表示以\(x\)為根的子樹內有\(i\)個監聽器,\(x\)有沒有放,\(x\)有沒有被監聽

      尤其注意的是,后兩個狀態表示\(v\)之前的合并完了,還沒有合并\(v\)的狀態

      所以在式子中,等號左邊的\(dp_{x,...}\)表示已經將\(v\)并入后\(x\)的狀態,右邊的則沒有,分討的依據也是\(v\)并入后的狀態

      分討見第一篇tj,就是根據后兩位共\(2 \times 2 = 4\)種情況討論

      游園會

      屌題

      \(dp\)\(dp\),說白了,就是記錄答案的\(dp\)有一維需要用另一個\(dp\)轉移,而不是之前的枚舉或是位運算

      拿這道題來說,狀壓\(LCS\)的差分數組作為一維\(S\),這一維度轉移時需要枚舉字符做一遍\(LCS\)\(dp\)得到\(newS\),從而實現答案的匯總與轉移

      還有一種理解是用\(LCS\)的大炮搭了個自動機去跑,畫出來也很直觀(圖為樣例),每一根線都是當前枚舉字符下做一遍\(LCS\),每個括號就是一個答案\(dp\)的狀態三元組:\(dp_{i,S,0/1/2}\)表示當前在第\(i\)位,\(LCS\)差分狀態為\(S\),匹配到\(NOI\)的第\(0\)(沒配上)\(/1/2\)位。其中第三維是為了防止出現\(NOI\),來決定當前位可以放什么

      Add and Remove

      無語題

      改刪為加,然后發現有個奇妙的東西:在兩個元素中間插入\(x\),那么\(x\)的貢獻就是兩個元素計入答案的次數之和與\(x\)的乘積

      然后你發現\(a_1\)\(a_n\)都只會被計入一次

      直接一個暴搜,\(dfs(l,r,numl,numr)\),分別記錄當前區間的左右端點以及對應的計入次數,枚舉新加入的元素將原區間分成兩個子區間:\(dfs(l,p,numl,numl + numr) + dfs(p,r,numl + numr,numr)\),遞歸取min

      完了

      posted @ 2024-10-16 22:33  why?123  閱讀(16)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成人资源在线观看| 日本伊人色综合网| 人人妻人人澡人人爽人人精品av | 成人无码午夜在线观看| 欧美大屁股xxxx高跟欧美黑人| 九九热在线免费视频观看| 十八禁国产精品一区二区| 成人网站免费观看永久视频下载| 精品久久久久久无码不卡| 69精品无人区国产一区| 九色精品国产亚洲av麻豆一| 亚洲国产午夜福利精品| 无码av岛国片在线播放| 中文字幕av一区二区| 久久99国产乱子伦精品免费| 成人国产av精品免费网| 人妻少妇偷人精品免费看| 在线观看视频一区二区三区| 日本国产精品第一页久久| 在线亚洲午夜片av大片| 久久精品国产亚洲不av麻豆| 四虎永久精品免费视频| 国内偷自第一区二区三区| 午夜大片免费男女爽爽影院| 亚洲 欧美 综合 另类 中字| 99麻豆久久精品一区二区| av午夜福利一片免费看久久| 人人干人人噪人人摸| 91亚洲国产成人精品性色| 亚洲精品熟女一区二区| 无码福利一区二区三区| 高清无打码一区二区三区| 精品亚洲男人一区二区三区| 风韵丰满熟妇啪啪区老熟熟女 | 色综合五月伊人六月丁香| 国产精品久久久久孕妇| 亚洲人成网线在线播放VA | 色综合人人超人人超级国碰 | 久久精品国产88精品久久| 久久99精品久久久久久9| 果冻传媒mv免费播放在线观看|