乙個長度為
n n
的環 a' role="presentation" style="position: relative;">a
a,如果環上有一對數 x,
y x,y
,當連線 x,
y x,y
的兩對弧中任意一對上不存在比 mi
n min
大的數,則稱 x,
y x,y
可以互相看見,問有多少對數可以互相看見。 3≤
n≤106
3 ≤n
≤10
6首先,與環有關的問題,最基本的思路就是段環成鏈。因為連線 x,
y x,y
的圓弧,一定不必穿過環上的最大值,所以可以去掉環上最大值並把環拆成鏈,最後重新算一遍最高點的貢獻即可。不難發現,將
x x
作為較低點,它能鏈結的點有左邊第乙個比它大的點和右邊第乙個比它大的點,於是想到單調棧。但是這樣有乙個問題,如果單調棧中出現了相同元素,那麼點
x' role="presentation" style="position: relative;">x
x還能連線到所有與
x x
大小相同的點。所以還要特殊處理這一類點。單調棧進行的過程中始終保持序列的遞減,那只用用
x' role="presentation" style="position: relative;">x
x替換棧內元素時,維護乙個
s s
陣列如果遇到相同元素,則通過累加得到與
x' role="presentation" style="position: relative;">x
x相同的元素個數即可。準確的說,是
x x
向左邊拓展,在遇到比它大的點時停下,中途遇到與
x' role="presentation" style="position: relative;">x
x相等的元素的個數(當然,除了將所有數的
s s
值加起來,也可以加上所有的 ck
2' role="presentation" style="position: relative;">c2k
ck2,其中
k k
為乙個滿足上述要求,值相等的點集中點的個數)。
由於這題有些卡語言,所以用
c' role="presentation" style="position: relative;">c
c語言交了
#include#define for(i,x,y) for(register int i=(x);i<=(y);++i)
#define dor(i,x,y) for(register int i=(x);i>=(y);--i)
#define n 1000003
typedef long long ll;
int mark[n];
int a[n],t[n],s[n],n;
int stk[n],top;
int p,mx=-1,h;
ll ans;
int main()
if(top)ans++;
stk[++top]=i;
}a[n+1]=2e9,stk[top=0]=n+1;
dor(i,n,1)
for(i,1,n)ans+=s[i];
h=-1;
for(i,1,n)}}
h=-1;
dor(i,n,1)}}
printf("%lld\n",ans);
return 0;
}
51Nod1482 部落訊號
題意 有n個部落圍成一圈,每個部落都有乙個高度,如果兩個部落之間的部落高度都低於這兩個部落的高度,那麼這兩個部落則互相可見,乙個部落從順時針或逆時針方向看到另乙個部落都算互相可見 題解 單調棧 乙個部落從順時針方向看到與它互相可見的部落,一定是一段連續遞增的序列,逆時針同理 這就很像單調棧的維護方式...
2150 部落戰爭
題目鏈結 題目大意 給出一張地圖,乙個軍隊要征戰整個土地。一塊土地只能經過一次,有x的地方不能走,軍隊只會走r c個格仔,只會向下走,問最少需要多少軍隊能夠征戰所有的土地 題解 比較 的dag最小路徑覆蓋,把可行點連邊,搞成二分圖就好了 我的收穫 水啊 include include include...
41 部落人乘法
41 部落人乘法 問題描述 明明熱愛數學,他的爸爸也有意培養明明對數學的興趣。一次,為了拓展明明的知識面,爸爸給明明講了乙個原始部落人計算乘法的方法 據說原始部落人以小石子作為計算工具,並用減半和加倍兩種運算就能求得任何兩個整數的乘積。其規則是 左邊不斷除2,寫下商,捨去餘數 右邊不斷加倍,直到左邊...