<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/scripts/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:h="http://www.w3.org/TR/html4/"><channel><title>santisify Site</title><description>to simplify technology to its purest, most powerful form.</description><link>https://santisify.top</link><item><title>Go并发编程</title><link>https://santisify.top/blog/other/go-concurrent-programming</link><guid isPermaLink="true">https://santisify.top/blog/other/go-concurrent-programming</guid><description>Go并发编程学习</description><pubDate>Wed, 01 Jul 2026 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;并发模型(CSP理论、Goroutine轻量级线程)&lt;/h2&gt;
&lt;h3&gt;基础概念&lt;/h3&gt;
&lt;p&gt;并发: 多个任务在同一时间段内交替执行, 但不一定同时执行, 也就是任务之间的切换是有序的, 任务之间是有依赖关系的.&lt;/p&gt;
&lt;p&gt;并行: 多个任务在同一时刻同时执行&lt;/p&gt;
&lt;p&gt;CSP理论:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;核心思想&lt;/strong&gt;: 不要通过共享内存来通信，而要通过通信来共享内存&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;组成要素&lt;/strong&gt;: &lt;code&gt;Process&lt;/code&gt; (进程\协程)、&lt;code&gt;Channel&lt;/code&gt; (通道)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;应用场景&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Goroutine&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;高并发Web服务器&lt;/strong&gt;：每个请求一个Goroutine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据处理流水线&lt;/strong&gt;：多个处理阶段并行执行&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;实时消息推送&lt;/strong&gt;：WebSocket连接管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;定时任务调度&lt;/strong&gt;：后台定时执行任务&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;并发爬虫&lt;/strong&gt;：同时抓取多个网页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;传统多线程与Goroutine的区别&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;| 特性 | 传统线程 | Goroutine |
|------|----------|-----------|
| 创建成本 | 1-2MB | 2KB |
| 创建速度 | 慢 | 快 |
| 调度方式 | 操作系统调度 | Go运行时调度 |
| 上下文切换 | 完整线程切换 | 用户态轻量切换 |&lt;/p&gt;
&lt;h2&gt;通道(Channel)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Channel&lt;/strong&gt;是Go语言中各个并发执行体间的&lt;strong&gt;通信机制&lt;/strong&gt;，是&lt;strong&gt;类型相关&lt;/strong&gt;的管道，用于在goroutine之间传递数据和同步执行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;不要通过共享内存来通信，而应通过通信来共享内存&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;// 创建channel
ch1 := make(chan int)        // 无缓冲channel 
ch2 := make(chan int, 10)   // 有缓冲channel，容量10

// 操作
ch1 &amp;#x3C;- 42    // 发送数据到channel
value := &amp;#x3C;-ch1 // 从channel接收数据
close(ch1)   // 关闭channel

// 特殊用法
value, ok := &amp;#x3C;-ch1 // 检查channel是否关闭
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;缓冲区区别&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无缓冲channel&lt;/strong&gt;：同步通信，发送和接收必须同时准备好&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;有缓冲channel&lt;/strong&gt;：异步通信，缓冲区满时发送阻塞，空时接收阻塞&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;fmt&quot;
    &quot;math/rand&quot;
    &quot;time&quot;
)

type Order struct {
    ID        int
    UserID    string
    Amount    float64
    Status    string
    CreatedAt time.Time
}

func orderProducer(orderChan chan&amp;#x3C;- Order, numOrders int) {
    for i := 1; i &amp;#x3C;= numOrders; i++ {
        order := Order{
            ID:        i,
            UserID:    fmt.Sprintf(&quot;user%d&quot;, rand.Intn(100)),
            Amount:    rand.Float64() * 1000,
            Status:    &quot;pending&quot;,
            CreatedAt: time.Now(),
        }
        orderChan &amp;#x3C;- order
        fmt.Printf(&quot;生成订单: ID=%d, 用户=%s, 金额=¥%.2f\n&quot;, 
            order.ID, order.UserID, order.Amount)
        time.Sleep(time.Millisecond * 100) // 模拟生成间隔
    }
    close(orderChan)
}

func orderProcessor(orderChan &amp;#x3C;-chan Order, resultChan chan&amp;#x3C;- Order) {
    for order := range orderChan {
        // 模拟订单处理逻辑
        processingTime := time.Duration(rand.Intn(300)) * time.Millisecond
        time.Sleep(processingTime)
        
        // 更新订单状态
        if order.Amount &gt; 500 {
            order.Status = &quot;verified&quot; // 大额订单需要验证
        } else {
            order.Status = &quot;completed&quot;
        }
        
        resultChan &amp;#x3C;- order
    }
	time.Sleep(time.Second * 1)
	close(resultChan)
}

func orderResultCollector(resultChan &amp;#x3C;-chan Order, done chan&amp;#x3C;- bool) {
    processedCount := 0
    for order := range resultChan {
        processedCount++
        fmt.Printf(&quot;处理完成: 订单ID=%d, 状态=%s, 金额=¥%.2f\n&quot;, 
            order.ID, order.Status, order.Amount)
    }
    fmt.Printf(&quot;所有订单处理完成! 总计: %d 个订单\n&quot;, processedCount)
    done &amp;#x3C;- true
}

func main() {
    rand.Seed(time.Now().UnixNano())
    
    // 创建管道
    orderChan := make(chan Order, 10)
    resultChan := make(chan Order, 10)
    done := make(chan bool)
    
    // 启动订单生成器
    go orderProducer(orderChan, 20)
    
    // 启动多个订单处理器（工人）
    for i := 1; i &amp;#x3C;= 3; i++ {
        go orderProcessor(orderChan, resultChan)
    }
    
    // 启动结果收集器
    go orderResultCollector(resultChan, done)
    
    // 等待所有处理完成
    &amp;#x3C;-done
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;select多路复用&lt;/strong&gt;：同时等待多个channel操作。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;fmt&quot;
    &quot;time&quot;
)

func main() {
    // 1. select多路复用
    ch1 := make(chan string)
    ch2 := make(chan string)
    
    go func() {
        time.Sleep(1 * time.Second)
        ch1 &amp;#x3C;- &quot;来自ch1&quot;
    }()
    
    go func() {
        time.Sleep(2 * time.Second)
        ch2 &amp;#x3C;- &quot;来自ch2&quot;
    }()
    
    for i := 0; i &amp;#x3C; 2; i++ {
        select {
        case msg1 := &amp;#x3C;-ch1:
            fmt.Println(&quot;收到:&quot;, msg1)
        case msg2 := &amp;#x3C;-ch2:
            fmt.Println(&quot;收到:&quot;, msg2)
        case &amp;#x3C;-time.After(3 * time.Second): // 超时控制
            fmt.Println(&quot;超时!&quot;)
            return
        }
    }
    
    // 2. 定时器与Ticker
    ticker := time.NewTicker(500 * time.Millisecond)
    done := make(chan bool)
    
    go func() {
        for {
            select {
            case &amp;#x3C;-done:
                return
            case t := &amp;#x3C;-ticker.C:
                fmt.Println(&quot;定时触发 at&quot;, t.Format(&quot;15:04:05&quot;))
            }
        }
    }()
    
    time.Sleep(2 * time.Second)
    ticker.Stop()
    done &amp;#x3C;- true
    fmt.Println(&quot;Ticker停止&quot;)
    
    // 3. 工作池模式
    jobs := make(chan int, 100)
    results := make(chan int, 100)
    
    // 启动3个worker
    for w := 1; w &amp;#x3C;= 3; w++ {
        go worker(w, jobs, results)
    }
    
    // 发送5个任务
    for j := 1; j &amp;#x3C;= 5; j++ {
        jobs &amp;#x3C;- j
    }
    close(jobs)
    
    // 收集结果
    for i:=0; i&amp;#x3C;=5; i++ {
		value := &amp;#x3C;-results
        fmt.Printf(&quot;Worker 处理结果 %d\n&quot;, value)
    }
}

func worker(id int, jobs &amp;#x3C;-chan int, results chan&amp;#x3C;- int) {
    for j := range jobs {
        fmt.Printf(&quot;Worker %d 处理任务 %d\n&quot;, id, j)
        time.Sleep(time.Second)
        results &amp;#x3C;- j * 2
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;同步原语（sync.Mutex互斥锁、sync.WaitGroup等待组、sync.RWMutex读写锁）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;为什么需要同步原语？&lt;/strong&gt;
在并发编程中，多个goroutine同时访问共享资源时会产生&lt;strong&gt;竞态条件&lt;/strong&gt;，导致数据不一致。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;sync.Mutex（互斥锁）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;保证同一时间只有一个goroutine能访问共享资源&lt;/li&gt;
&lt;li&gt;两个方法：&lt;code&gt;Lock()&lt;/code&gt; 和 &lt;code&gt;Unlock()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用后必须释放，否则会导致死锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;sync.RWMutex（读写锁）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;允许多个读操作或一个写操作&lt;/li&gt;
&lt;li&gt;读锁：&lt;code&gt;RLock()&lt;/code&gt; / &lt;code&gt;RUnlock()&lt;/code&gt;（共享锁）&lt;/li&gt;
&lt;li&gt;写锁：&lt;code&gt;Lock()&lt;/code&gt; / &lt;code&gt;Unlock()&lt;/code&gt;（互斥锁）&lt;/li&gt;
&lt;li&gt;适合&quot;读多写少&quot;的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;sync.WaitGroup（等待组）&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;等待一组goroutine完成工作&lt;/li&gt;
&lt;li&gt;三个方法：&lt;code&gt;Add()&lt;/code&gt;、&lt;code&gt;Done()&lt;/code&gt;、&lt;code&gt;Wait()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用于协调多个goroutine的执行顺序&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;var wg sync.WaitGroup

func main() {
    for i := 0; i &amp;#x3C; 3; i++ {
        wg.Add(1)        // 计数器+1
        go worker(i)
    }
    wg.Wait()           // 等待所有goroutine完成
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;fmt&quot;
    &quot;sync&quot;
    &quot;time&quot;
)

type Inventory struct {
    stock    int              // 库存数量
    rwMutex  sync.RWMutex     // 保护库存
}

// 查询库存（使用读写锁的读锁）
func (inv *Inventory) getStock() int {
    inv.rwMutex.RLock()
    defer inv.rwMutex.RUnlock()
    return inv.stock
}

// 扣减库存（使用互斥锁和读写锁的写锁）
func (inv *Inventory) deductStock(userID int, quantity int) bool {
    // 先检查库存（读锁）
    inv.rwMutex.Lock()
    defer inv.rwMutex.Unlock()
	
    // 检查，防止超卖
    if inv.stock &amp;#x3C; quantity {
        fmt.Printf(&quot;用户%d: 库存不足，扣减失败\n&quot;, userID)
        return false
    }
    
    inv.stock -= quantity
    fmt.Printf(&quot;用户%d: 成功购买%d件，剩余库存%d\n&quot;, userID, quantity, inv.stock)
    return true
}

func main() {
    inventory := &amp;#x26;Inventory{stock: 10} // 初始库存10件
    
    var wg sync.WaitGroup
    
    // 模拟100个用户同时抢购
    for i := 1; i &amp;#x3C;= 100; i++ {
        wg.Add(1)
        go func(userID int) {
            defer wg.Done()
            inventory.deductStock(userID, 1)
        }(i)
    }
    
    wg.Wait()
    fmt.Printf(&quot;最终库存: %d\n&quot;, inventory.getStock())
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;原子操作替代简单锁&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;import &quot;sync/atomic&quot;

type Counter struct {
    value int64
}

func (c *Counter) Increment() {
    atomic.AddInt64(&amp;#x26;c.value, 1) // 比mutex性能更好
}

func (c *Counter) Decrement() {
    atomic.AddInt64(&amp;#x26;c.value, -1) 
}

func (c *Counter) Value() int64 {
    return atomic.LoadInt64(&amp;#x26;c.value)
}

func main() {
	var counter Counter
    var wg sync.WaitGroup
  
    // 模拟100个用户同时点赞
    for i := 1; i &amp;#x3C;= 100; i++ {
      wg.Add(1)
      go func() {
          defer wg.Done()
          counter.Increment()
      }()
    }

    // 模拟10个用户取消点赞
    for i := 1; i &amp;#x3C;= 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            counter.Decrement()
        }()
    }
  
    wg.Wait()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;并发模式（生产者-消费者、扇入/扇出、Pipeline）&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;生产者-消费者模式&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;生产者-消费者模式是并发编程中最经典的模式之一，解决生产者和消费者速度不匹配的问题。&lt;/li&gt;
&lt;li&gt;就像食堂阿姨打饭和同学们吃饭，赚钱和花钱的关系是一样的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;扇入/扇出模式&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;扇出&lt;/strong&gt;：一个channel分发给多个goroutine处理（一产多消）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;扇入&lt;/strong&gt;：多个channel合并到一个channel（多产一消）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Pipeline模式&lt;/strong&gt;：将复杂任务分解为多个处理阶段，每个阶段通过channel连接，形成处理流水线。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;fmt&quot;
    &quot;math/rand&quot;
    &quot;sync&quot;
    &quot;time&quot;
)

// 订单结构
type Order struct {
    ID       int
    UserID   int
    Amount   float64
    Status   string
    CreateAt time.Time
}

// 1. 生产者-消费者：订单生成与处理
func orderProducer(orderCh chan&amp;#x3C;- Order, count int) {
    defer close(orderCh)
    for i := 1; i &amp;#x3C;= count; i++ {
        order := Order{
            ID:       i,
            UserID:   rand.Intn(1000) + 1,
            Amount:   rand.Float64() * 1000,
            Status:   &quot;pending&quot;,
            CreateAt: time.Now(),
        }
        fmt.Printf(&quot;生成订单: ID=%d, 金额=¥%.2f\n&quot;, order.ID, order.Amount)
        orderCh &amp;#x3C;- order
        time.Sleep(100 * time.Millisecond) // 模拟生成间隔
    }
}

func orderConsumer(orderCh &amp;#x3C;-chan Order, wg *sync.WaitGroup) {
    defer wg.Done()
    for order := range orderCh {
        // 模拟订单处理
        time.Sleep(200 * time.Millisecond)
        order.Status = &quot;processed&quot;
        fmt.Printf(&quot;处理订单: ID=%d, 状态=%s\n&quot;, order.ID, order.Status)
    }
}

// 2. 扇出模式：一个订单流分发给多个处理器
func fanOutProcessor(input &amp;#x3C;-chan Order, workerID int, wg *sync.WaitGroup) {
    defer wg.Done()
    for order := range input {
        // 不同的处理器做不同的处理
        switch workerID {
        case 1:
            // 处理器1：计算折扣
            discount := order.Amount * 0.1
            fmt.Printf(&quot;处理器%d计算折扣: 订单%d 优惠¥%.2f\n&quot;, 
                workerID, order.ID, discount)
        case 2:
            // 处理器2：发送通知
            fmt.Printf(&quot;处理器%d发送通知: 订单%d创建成功\n&quot;, 
                workerID, order.ID)
        case 3:
            // 处理器3：记录日志
            fmt.Printf(&quot;处理器%d记录日志: 订单%d金额¥%.2f\n&quot;, 
                workerID, order.ID, order.Amount)
        }
        time.Sleep(150 * time.Millisecond)
    }
}

// 3. 扇入模式：多个数据源合并
func fanInProducer(producerID int, output chan&amp;#x3C;- Order) {
    defer fmt.Printf(&quot;生产者%d结束\n&quot;, producerID)
    for i := 1; i &amp;#x3C;= 3; i++ {
        order := Order{
            ID:     producerID*100 + i,
            UserID: producerID,
            Amount: float64(producerID*100 + i),
            Status: &quot;new&quot;,
        }
        fmt.Printf(&quot;生产者%d生成订单: %d\n&quot;, producerID, order.ID)
        output &amp;#x3C;- order
        time.Sleep(time.Duration(producerID) * 100 * time.Millisecond)
    }
}

// 4. Pipeline模式：订单处理流水线
func validationStage(input &amp;#x3C;-chan Order) &amp;#x3C;-chan Order {
    output := make(chan Order, 10)
    go func() {
        defer close(output)
        for order := range input {
            // 第一阶段：订单验证
            time.Sleep(50 * time.Millisecond)
            if order.Amount &gt; 0 {
                order.Status = &quot;validated&quot;
                fmt.Printf(&quot;验证通过: 订单%d\n&quot;, order.ID)
                output &amp;#x3C;- order
            } else {
                fmt.Printf(&quot;验证失败: 订单%d金额异常\n&quot;, order.ID)
            }
        }
    }()
    return output
}

func paymentStage(input &amp;#x3C;-chan Order) &amp;#x3C;-chan Order {
    output := make(chan Order, 10)
    go func() {
        defer close(output)
        for order := range input {
            // 第二阶段：支付处理
            time.Sleep(100 * time.Millisecond)
            order.Status = &quot;paid&quot;
            fmt.Printf(&quot;支付成功: 订单%d\n&quot;, order.ID)
            output &amp;#x3C;- order
        }
    }()
    return output
}

func shippingStage(input &amp;#x3C;-chan Order) &amp;#x3C;-chan Order {
    output := make(chan Order, 10)
    go func() {
        defer close(output)
        for order := range input {
            // 第三阶段：发货处理
            time.Sleep(150 * time.Millisecond)
            order.Status = &quot;shipped&quot;
            fmt.Printf(&quot;发货完成: 订单%d\n&quot;, order.ID)
            output &amp;#x3C;- order
        }
    }()
    return output
}

func main() {
    rand.Seed(time.Now().UnixNano())
    
    fmt.Println(&quot;=== 1. 生产者-消费者模式演示 ===&quot;)
    // 创建订单channel
    orderCh := make(chan Order, 5)
    var wg sync.WaitGroup
    
    // 启动消费者
    wg.Add(2)
    go orderConsumer(orderCh, &amp;#x26;wg)
    go orderConsumer(orderCh, &amp;#x26;wg)
    
    // 启动生产者
    go orderProducer(orderCh, 6)
    
    wg.Wait()
    
    fmt.Println(&quot;\n=== 2. 扇出模式演示 ===&quot;)
    // 扇出：一个输入，多个处理器
    fanOutCh := make(chan Order, 10)
    var fanOutWg sync.WaitGroup
    
    // 启动3个处理器
    fanOutWg.Add(3)
    for i := 1; i &amp;#x3C;= 3; i++ {
        go fanOutProcessor(fanOutCh, i, &amp;#x26;fanOutWg)
    }
    
    // 生产一些测试数据
    go func() {
        for i := 1; i &amp;#x3C;= 6; i++ {
            fanOutCh &amp;#x3C;- Order{ID: i, Amount: float64(i * 100)}
        }
        close(fanOutCh)
    }()
    
    fanOutWg.Wait()
    
    fmt.Println(&quot;\n=== 3. 扇入模式演示 ===&quot;)
    // 扇入：多个生产者，一个输出
    fanInCh := make(chan Order, 10)
    
    // 启动3个生产者
    for i := 1; i &amp;#x3C;= 3; i++ {
        go fanInProducer(i, fanInCh)
    }
    
    // 收集结果
    go func() {
        time.Sleep(2 * time.Second)
        close(fanInCh)
    }()
    
    fmt.Println(&quot;收集到的订单:&quot;)
    for order := range fanInCh {
        fmt.Printf(&quot;  订单ID: %d, 金额: ¥%.2f\n&quot;, order.ID, order.Amount)
    }
    
    fmt.Println(&quot;\n=== 4. Pipeline模式演示 ===&quot;)
    // 创建初始输入
    pipelineInput := make(chan Order, 10)
    
    // 构建流水线
    validatedOrders := validationStage(pipelineInput)
    paidOrders := paymentStage(validatedOrders)
    shippedOrders := shippingStage(paidOrders)
    
    // 发送测试订单到流水线
    go func() {
        for i := 1; i &amp;#x3C;= 3; i++ {
            pipelineInput &amp;#x3C;- Order{
                ID:     i,
                UserID: i * 10,
                Amount: float64(i * 50),
                Status: &quot;new&quot;,
            }
        }
        close(pipelineInput)
    }()
    
    // 收集最终结果
    fmt.Println(&quot;流水线处理结果:&quot;)
    for order := range shippedOrders {
        fmt.Printf(&quot;  完成: 订单%d, 状态: %s\n&quot;, order.ID, order.Status)
    }
    
    fmt.Println(&quot;\n🎉 所有并发模式演示完成!&quot;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;带错误处理的并发模式&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;errors&quot;
    &quot;fmt&quot;
    &quot;sync&quot;
    &quot;time&quot;
)

type Result struct {
    Value int
    Error error
}

// 带错误处理的生产者-消费者
func safeProducer(ch chan&amp;#x3C;- Result, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 1; i &amp;#x3C;= 5; i++ {
        // 模拟偶尔出错
        if i == 3 {
            ch &amp;#x3C;- Result{Error: errors.New(&quot;模拟错误&quot;)}
        } else {
            ch &amp;#x3C;- Result{Value: i}
        }
        time.Sleep(100 * time.Millisecond)
    }
	close(ch)
}

func safeConsumer(ch &amp;#x3C;-chan Result, wg *sync.WaitGroup) {
    defer wg.Done()
    for result := range ch {
        if result.Error != nil {
            fmt.Printf(&quot;处理出错: %v\n&quot;, result.Error)
        } else {
            fmt.Printf(&quot;处理成功: %d\n&quot;, result.Value)
        }
    }
}

func main() {
    fmt.Println(&quot;=== 带错误处理的并发 ===&quot;)
    
    resultCh := make(chan Result, 5)
    var safeWg sync.WaitGroup
    
    safeWg.Add(2)
    go safeProducer(resultCh, &amp;#x26;safeWg)
    go safeConsumer(resultCh, &amp;#x26;safeWg)
    
    safeWg.Wait()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;网络基础（TCP/IP协议、三次握手、端口概念）&lt;/h2&gt;
&lt;h3&gt;核心概念&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;TCP/IP协议族&lt;/strong&gt;是互联网通信的基础，就像现实世界的&lt;strong&gt;邮政系统&lt;/strong&gt;一样，负责数据的可靠传输。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TCP/IP四层模型&lt;/strong&gt;（类比快递系统）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用层 - 你的信件内容（HTTP、FTP、SMTP）&lt;/li&gt;
&lt;li&gt;传输层 - 快递包装和物流单（TCP、UDP）&lt;/li&gt;
&lt;li&gt;网络层 - 地址和路由（IP协议）&lt;/li&gt;
&lt;li&gt;网络接口层 - 运输工具（以太网、WiFi）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;TCP vs UDP 核心区别&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;TCP - 可靠传输，像打电话&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要建立连接（三次握手）&lt;/li&gt;
&lt;li&gt;保证数据顺序和完整性&lt;/li&gt;
&lt;li&gt;自动重传丢失的数据&lt;/li&gt;
&lt;li&gt;适合：网页浏览、文件传输、邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UDP - 不可靠传输，像发短信&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;无需建立连接&lt;/li&gt;
&lt;li&gt;不保证数据到达顺序&lt;/li&gt;
&lt;li&gt;可能丢失数据包&lt;/li&gt;
&lt;li&gt;适合：视频流、游戏、DNS查询&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;三次握手详解&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;TCP连接建立过程&lt;/strong&gt; - 就像确认双方都能正常沟通：
&lt;img src=&quot;https://gh-proxy.com/https://github.com/yuanqinguo/flyfei/blob/master/docs/golang/images/tcp-connect.png&quot; alt=&quot;tcp-connect.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;为什么需要三次握手？&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;防止历史连接&lt;/strong&gt;：避免网络延迟导致的重复连接请求&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;同步序列号&lt;/strong&gt;：确保双方都知道对方的起始序号&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;确认双向可达&lt;/strong&gt;：证明客户端和服务器都能正常收发数据&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;端口概念与应用&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;端口的作用&lt;/strong&gt; - 就像公司的分机号，员工号：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;80:  HTTP - 网页浏览&lt;/li&gt;
&lt;li&gt;443:  HTTPS - 安全网页&lt;/li&gt;
&lt;li&gt;22:   SSH - 安全远程登录&lt;/li&gt;
&lt;li&gt;53:   DNS - 域名解析&lt;/li&gt;
&lt;li&gt;3306: MySQL - 数据库&lt;/li&gt;
&lt;li&gt;5432: PostgreSQL - 数据库&lt;/li&gt;
&lt;li&gt;6379: Redis - 缓存数据库&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
	&quot;net&quot;
	&quot;sync&quot;
)

type ChatRoom struct {
	clients map[net.Conn]string
	mutex   sync.RWMutex
}

func NewChatRoom() *ChatRoom {
	return &amp;#x26;ChatRoom{
		clients: make(map[net.Conn]string),
	}
}

func (cr *ChatRoom) broadcast(sender net.Conn, msg string) {
	cr.mutex.RLock()
	defer cr.mutex.RUnlock()
	for client, name := range cr.clients {
		if sender == client {
			continue
		}
		client.Write([]byte(name + &quot;: &quot; + msg))
	}
}

func (cr *ChatRoom) handleConnection(conn net.Conn) {
	defer conn.Close()

	conn.Write([]byte(&quot;请输入你的昵称：&quot;))
	name := make([]byte, 1024)
	n, _ := conn.Read(name)
	cr.mutex.Lock()
	cr.clients[conn] = string(name[:n-1])
	cr.mutex.Unlock()
	username := string(name[:n-1])
	cr.broadcast(conn, fmt.Sprintf(&quot;系统: %s 加入了聊天室\n&quot;, username))

	for {
		readBuff := make([]byte, 1024)
		n, err := conn.Read(readBuff)
		if err != nil {
			break
		}

		message := string(readBuff[:n])
		if message == &quot;quit\n&quot; {
			break
		}
		cr.broadcast(conn, fmt.Sprintf(&quot;%s: %s\n&quot;, username, message))
	}
	cr.mutex.Lock()
	delete(cr.clients, conn)
	cr.mutex.Unlock()
	cr.broadcast(conn, fmt.Sprintf(&quot;系统: %s 离开了聊天室&quot;, username))
}

func main() {
	chatRoom := NewChatRoom()
	listener, err := net.Listen(&quot;tcp&quot;, &quot;:8080&quot;)
	if err != nil {
		panic(err)
	}

	defer listener.Close()
	fmt.Println(&quot;启动监听成功&quot;)
	for {
		conn, _ := listener.Accept()
		go chatRoom.handleConnection(conn)
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;HTTP编程（net/http包、创建HTTP服务器、处理请求与响应）&lt;/h2&gt;
&lt;h3&gt;什么是HTTP？&lt;/h3&gt;
&lt;p&gt;HTTP（HyperText Transfer Protocol，超文本传输协议）是互联网上应用最为广泛的一种网络协议，用于客户端和服务器之间的通信。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心特点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;无状态协议&lt;/strong&gt;：每次请求都是独立的，服务器不保留之前请求的信息&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于请求-响应模型&lt;/strong&gt;：客户端发起请求，服务器返回响应&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;应用层协议&lt;/strong&gt;：建立在TCP/IP协议之上&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;明文传输&lt;/strong&gt;：数据不加密（HTTPS是加密版本）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;HTTP请求-响应流程&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;客户端 (浏览器/APP)       服务器 (Web服务)
     |                         |
     | --- HTTP请求  -------&gt;  |
     |                         | 
     | &amp;#x3C;--- HTTP响应 --------  |
     |                         |
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;HTTP请求组成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;GET /api/students HTTP/1.1          ← 请求行（方法 + URL + 协议版本）
Host: localhost:8080                ← 请求头（元数据）
Content-Type: application/json
Authorization: Bearer token123
                                   ← 空行分隔
{&quot;name&quot;: &quot;张三&quot;, &quot;age&quot;: 20}         ← 请求体（可选，POST/PUT时有）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;HTTP方法语义：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET&lt;/code&gt;：获取资源（查）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;POST&lt;/code&gt;：创建资源（增）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PUT&lt;/code&gt;：更新资源（改）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DELETE&lt;/code&gt;：删除资源（删）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PATCH&lt;/code&gt;：部分更新&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;HTTP响应组成&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK                     ← 状态行（协议版本 + 状态码 + 描述）
Content-Type: application/json      ← 响应头（元数据）
Content-Length: 45
Date: Mon, 23 Oct 2023 08:00:00 GMT
                                   ← 空行分隔
{&quot;id&quot;: 1, &quot;name&quot;: &quot;张三&quot;, &quot;age&quot;: 20} ← 响应体（数据内容）
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;常见状态码：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;200 OK&lt;/code&gt;：请求成功&lt;/li&gt;
&lt;li&gt;&lt;code&gt;201 Created&lt;/code&gt;：资源创建成功&lt;/li&gt;
&lt;li&gt;&lt;code&gt;400 Bad Request&lt;/code&gt;：客户端请求错误&lt;/li&gt;
&lt;li&gt;&lt;code&gt;401 Unauthorized&lt;/code&gt;：未认证&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404 Not Found&lt;/code&gt;：资源不存在&lt;/li&gt;
&lt;li&gt;&lt;code&gt;500 Internal Server Error&lt;/code&gt;：服务器内部错误&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;net/http包架构&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;客户端请求
    ↓
http.ServeMux (路由 multiplexer) 
    ↓
http.Handler (处理器接口)
    ↓  
具体处理逻辑 (HandlerFunc或自定义Handler)
    ↓
http.ResponseWriter (写回响应)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;核心组件说明&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. 路由 (ServeMux)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;负责将不同的URL路径映射到对应的处理器&lt;/li&gt;
&lt;li&gt;可以创建多个路由，但通常一个应用使用一个主路由&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;2. 处理器 (Handler)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;// Handler是一个接口，只需要实现一个方法
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;3. 处理器函数 (HandlerFunc)&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;// 函数签名，与ServeHTTP方法相同
type HandlerFunc func(ResponseWriter, *Request)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;4. 请求对象 (Request)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;包含客户端的全部请求信息&lt;/li&gt;
&lt;li&gt;方法、URL、请求头、请求体等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5. 响应写入器 (ResponseWriter)&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用于构建和发送响应回客户端&lt;/li&gt;
&lt;li&gt;可以设置状态码、响应头、写入响应体&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
	&quot;net/http&quot;
)

func main() {
	mux := http.NewServeMux()
	mux.HandleFunc(&quot;/students&quot;, func(w http.ResponseWriter, r *http.Request) {
		w.Header().Add(&quot;Content-Type&quot;, &quot;application/json&quot;)
		if r.Method == http.MethodGet {
			fmt.Fprintf(w, `[{&quot;id&quot; : 1, &quot;name&quot;: &quot;张三&quot;, &quot;age&quot;: 20}]`)
			return
		}
		http.Error(w, &quot;Method Not Allowed&quot;, http.StatusMethodNotAllowed)
	})

	http.ListenAndServe(&quot;:8080&quot;, mux)
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Websocket&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;WebSocket是什么？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;想象一下你和朋友打电话的场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HTTP&lt;/strong&gt;：像发短信，每次都要建立连接→发送→断开，不能实时对话&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebSocket&lt;/strong&gt;：像打电话，一次接通后双方可以随时说话，实现真正的实时对话&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;WebSocket核心特点&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;一次握手，长久连接&lt;/strong&gt;：客户端发起WebSocket请求，服务端同意后建立持久连接&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;双向通信&lt;/strong&gt;：服务端可以主动向客户端推送数据，不再需要客户端轮询&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;低延迟&lt;/strong&gt;：避免了HTTP每次请求的头部开销和连接建立时间&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;协议升级&lt;/strong&gt;：基于HTTP协议升级而来（HTTP 101状态码）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;WebSocket握手过程&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;客户端请求：
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade

服务端响应：
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;为什么需要gorilla/websocket库？&lt;/strong&gt;
Go标准库没有提供完整的WebSocket实现，gorilla/websocket是业界最成熟的选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;处理了WebSocket协议细节&lt;/li&gt;
&lt;li&gt;提供了连接管理、消息读写等高级功能&lt;/li&gt;
&lt;li&gt;有良好的错误处理和连接状态管理&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
    &quot;fmt&quot;
    &quot;log&quot;
    &quot;net/http&quot;

    &quot;github.com/gorilla/websocket&quot;
)

// 创建WebSocket升级器
var upgrader = websocket.Upgrader{
    // 允许所有跨域请求（生产环境应该严格限制）
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

func main() {
    // 设置WebSocket路由
    http.HandleFunc(&quot;/ws&quot;, handleWebSocket)
    
    // 启动静态文件服务（用于提供HTML页面）
    http.Handle(&quot;/&quot;, http.FileServer(http.Dir(&quot;./public&quot;)))
    
    fmt.Println(&quot;WebSocket服务器启动在 :8080&quot;)
    fmt.Println(&quot;访问 http://localhost:8080 测试聊天功能&quot;)
    log.Fatal(http.ListenAndServe(&quot;:8080&quot;, nil))
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    // 1. 升级HTTP连接到WebSocket连接
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(&quot;升级WebSocket失败:&quot;, err)
        return
    }
    defer conn.Close() // 确保连接最终会关闭
    
    fmt.Println(&quot;新的WebSocket连接建立!&quot;)
    
    // 2. 持续监听和处理消息
    for {
        // 读取客户端发送的消息
        messageType, message, err := conn.ReadMessage()
        if err != nil {
            log.Println(&quot;读取消息失败:&quot;, err)
            break
        }
        
        fmt.Printf(&quot;收到消息: %s\n&quot;, message)
        
        // 3. 向客户端回送消息
        response := fmt.Sprintf(&quot;服务器回复: 收到你的消息 &apos;%s&apos;&quot;, message)
        err = conn.WriteMessage(messageType, []byte(response))
        if err != nil {
            log.Println(&quot;发送消息失败:&quot;, err)
            break
        }
    }
    
    fmt.Println(&quot;WebSocket连接关闭&quot;)
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/golang.CC2e5hUs.png"/><enclosure url="/_astro/golang.CC2e5hUs.png"/></item><item><title>golang学习之路：从入门到实践</title><link>https://santisify.top/blog/other/golang-learn</link><guid isPermaLink="true">https://santisify.top/blog/other/golang-learn</guid><description>Go基础学习</description><pubDate>Fri, 19 Jun 2026 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;本人比较看重go的简洁性、跨平台不依赖运行时环境以及高并发（都是相对于Java），同时，我也比较侧重于后端开发，毕竟大部分理工男（懂的都懂）&lt;/p&gt;
&lt;p&gt;我也算是开始自己的go语言学习了，但愿不要想java那样......&lt;/p&gt;
&lt;h2&gt;基础语法&lt;/h2&gt;
&lt;h3&gt;变量和常量数据类型&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;//常量定义
const (
	StatusOK           = iota + 1    //iota是go语言的一个预定义标识符，表示常量生成器，在const关键字出现时被重置为0，并在每个const声明中自动递增。     
	StatusBadRequest                 //2
	StatusUnauthorized               //3
	MB                 = 1024 * 1024 //1048576
)

//变量定义
func main() {
	var str1 string = &quot;Hello Go 1&quot; //标准定义
	var str2 = &quot;Hello Go 2&quot;        //类型推断

	str3 := &quot;Hello Go 3&quot;          //短定义（通常用于函数中）
	fmt.Println(str1, str2, str3) //output：Hello Go 1 Hello Go 2 Hello Go 3
	str1, str2 = str2, str1       //交换str1与str2的值
	fmt.Println(str1, str2, str3) // output：Hello Go 2 Hello Go 1 Hello Go 3
}

//空值
func testNonInitValue() {
	var a int
	var b string
	var c float64
	fmt.Println(a, b, c) //output: 0 “” 0
	//上一行b输出的结果代表b的值是一个空字符串，而不是null或者undefined。
}


//至于类型转换，认真学过Java都知道
...略

//类型自定义
type ll int64 // 定义一个新的类型ll，它的底层类型是int64
//为ll类型实现String方法，使其满足fmt.Stringer接口
func (l ll) String() string {
	return fmt.Sprintf(&quot;%d&quot;, l)
}
//结构体
type UserValue struct {
	name  string
	age   int
	email string
}
//同理，结构体也可以实现String方法
func (u UserValue) String() string {
	return fmt.Sprintf(&quot;name:%s, age:%d, email:%s)&quot;, u.name, u.age, u.email)
}
// slice
var arr [3]int       //只定义，为使用 output: 0,0,0
b := [3]int{1, 2, 3} //临时定义，并且附上初值 output:1,2,3
var c []int          //不定长
c1 = append(c, 1,2,3,4,5)
c2 := []int{1,2,3,4,5}
sc1 := make([]int, 0, len(c1)) // make函数创建一个长度为0，容量为len(c1)的切片
sc2 := new ([]int) // new函数创建一个指向长度为0的切片的指针

//map 键值对
m1 := map[string]int{&quot;a&quot;: 1, &quot;b&quot;: 2} //定义并初始化一个map output: map[a:1 b:2]
m2 := make(map[string]int)              //使用make函数创建一个空的map
m2[&quot;c&quot;] = 3 //向map中添加一个键值对
for k, v := range m1 { // 使用range关键字遍历map，k代表键，v代表值
    fmt.Printf(&quot;key: %s, value: %d\n&quot;, k, v) //output: key: a, value: 1 \n key: b, value: 2
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;流程控制&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;//if语句
if x &gt; 0 {
    fmt.Println(&quot;x is positive&quot;)
} else if x &amp;#x3C; 0 {
    fmt.Println(&quot;x is negative&quot;)
} else {
    fmt.Println(&quot;x is zero&quot;)
}

//switch语句
switch day := time.Now().Weekday(); day {
case time.Monday:
    fmt.Println(&quot;It&apos;s Monday&quot;)
case time.Tuesday:
    fmt.Println(&quot;It&apos;s Tuesday&quot;)
default:
    fmt.Println(&quot;It&apos;s another day&quot;)
}

//for循环
for i := 0; i &amp;#x3C; 5; i++ {
    fmt.Println(i) //output: 0 1 2 3 4
}

//goto语句
func example() {
    fmt.Println(&quot;Start&quot;)
    goto Skip
    fmt.Println(&quot;This will be skipped&quot;)
Skip:
    fmt.Println(&quot;End&quot;)
}
//output: Start \n End

//select语句
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
    time.Sleep(1 * time.Second)
    ch1 &amp;#x3C;- &quot;Hello from channel 1&quot;
}()
go func() {
    time.Sleep(2 * time.Second)
    ch2 &amp;#x3C;- &quot;Hello from channel 2&quot;
}()
select {
case msg1 := &amp;#x3C;-ch1: 
    fmt.Println(msg1) //output: Hello from channel 1
case msg2 := &amp;#x3C;-ch2:
    fmt.Println(msg2) //output: Hello from channel 2
case &amp;#x3C;-time.After(3 * time.Second):
    fmt.Println(&quot;Timeout&quot;)
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;函数和方法&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;//函数定义
func add(a int, b int) int {
	return a + b
}
//函数调用
result := add(3, 5) //output: 8
//方法定义
type Rectangle struct {
	width  float64
	height float64
}
func (r Rectangle) Area() float64 {
	return r.width * r.height
}
//方法调用
rect := Rectangle{width: 4, height: 5}
area := rect.Area() //output: 20

// 匿名函数
func() {
	fmt.Println(&quot;This is an anonymous function&quot;)
}() //output: This is an anonymous function

// 闭包
func makeAdder(x int) func(int) int {
	return func(y int) int {
		return x + y
	}
}
add5 := makeAdder(5)
result := add5(3) //output: 8

//可变参数
func sum(nums ...int) int {
	total := 0
	for _, num := range nums {
		total += num
	}
	return total
}
result := sum(1, 2, 3, 4) //output: 10
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;指针&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;//指针定义
var p *int //定义一个指向int类型的指针
//指针赋值
x := 10
p = &amp;#x26;x //将变量x的地址赋值给指针p
//指针解引用
value := *p //通过指针p获取x的值 output: 10
//指针修改值
*p = 20 //通过指针p修改x的值
fmt.Println(x) //output: 20

//指针与函数
func increment(n *int) {
	*n++ //通过指针n修改传入的值
}
num := 5
increment(&amp;#x26;num) //传入num的地址
fmt.Println(num) //output: 6	

//指针与结构体
type Point struct {
	x int
	y int
}
p1 := Point{x: 1, y: 2}
p2 := &amp;#x26;p1 //创建一个指向p1的指针
p2.x = 3 //通过指针p2修改p1的x值
fmt.Println(p1) //output: {3 2}

//指针与切片
func modifySlice(s []int) {
	s[0] = 100 //修改切片的第一个元素
}
slice := []int{1, 2, 3}
modifySlice(slice) //传入切片
fmt.Println(slice) //output: [100 2 3]

//二级指针
x := 10
p := &amp;#x26;x
pp := &amp;#x26;p
fmt.Println(&quot;x:&quot;, x, &quot;p:&quot;, p, &quot;pp:&quot;, pp, &quot;**pp:&quot;, **pp) //output: x: 10 p:随机地址 pp: 随机地址 **pp: 10
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;错误处理&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;//error类型
type error interface {
	Error() string
}

//defer语句
func example() {
	defer fmt.Println(&quot;This will be printed last&quot;)
	fmt.Println(&quot;This will be printed first&quot;)
}//output: This will be printed first \n This will be printed last

//panic和recover
func example() {
	defer func() {
		if r := recover(); r != nil {
			fmt.Println(&quot;Recovered from panic:&quot;, r)
		}
	}()
	panic(&quot;Something went wrong&quot;) //触发panic
	fmt.Println(&quot;This will not be printed&quot;)
}//output: Recovered from panic: Something went wrong
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Error样例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
	&quot;os&quot;
	&quot;time&quot;
)

const (
	TimeFmt = &quot;2006-01-02 15:04:05&quot;
)

func main() {
	username, err := queryDatabase(100)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(username)
	}

	err = readFile(&quot;test.txt&quot;)
	if err != nil {
		fmt.Println(err)
	}

	a := []int{2, 4, 1, 24, 4, 32, 1, 243, 65, 43, 765, 23, 234}
	res, err := safeAccess(a, 100)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(res)
	}

	defres := deferReturn()
	fmt.Println(&quot;deferResult:&quot;, defres)
}

type BusinessError struct {
	Code    int
	Message string
	Time    time.Time
}

func (e *BusinessError) Error() string {
	return fmt.Sprintf(&quot;错误代码: %d \n 消息: %s \n 时间:%s \n&quot;,
		e.Code, e.Message, e.Time.Format(TimeFmt))
}

func queryDatabase(userID int) (string, error) {
	if userID &amp;#x3C;= 0 {
		return &quot;&quot;, &amp;#x26;BusinessError{
			Code:    400,
			Message: &quot;用户不存在&quot;,
			Time:    time.Now(),
		}
	}
	if userID == 999 { //数据库连接超时
		return &quot;&quot;, &amp;#x26;BusinessError{
			Code:    401,
			Message: &quot;数据库连接超时&quot;,
			Time:    time.Now(),
		}
	}
	return &quot;李四&quot;, nil
}

func readFile(fileName string) error {
	file, err := os.Open(fileName)
	if err != nil {
		return fmt.Errorf(&quot;打开文件失败: %w&quot;, err)
	}
	defer file.Close()
	buf := make([]byte, 1024)
	_, err = file.Read(buf)
	if err != nil {
		return fmt.Errorf(&quot;读取文件失败: %w&quot;, err)
	}
	return nil
}

func safeAccess(arr []int, index int) (result int, err error) {
	defer func() {
		if r := recover(); r != nil {
			err = fmt.Errorf(&quot;panic: %v&quot;, r)
		}
	}()
	return arr[index], nil
}

func deferReturn() (result int) {  
	defer func() {  // [!code highlight:4]
		result++
	}()
	return 10
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;方法&lt;/h2&gt;
&lt;p&gt;方法定义：&lt;/p&gt;
&lt;p&gt;绑定一个已定义类型的函数称为方法。方法与函数的区别在于，方法有一个特殊的接收者参数，它表示调用该方法的实例。接收者可以是值类型或指针类型。&lt;/p&gt;
&lt;p&gt;已定义类型须为我们自己定义的类型，不能是内置类型（如int、string等），也不能是其他包中定义的类型。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;func (接收者 接收者类型) 方法名(参数列表) 返回值列表 {
	// 方法体
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接收者类型：值接收者（不改变参数值），指针接收者（改变参数值）&lt;/p&gt;
&lt;p&gt;样例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import &quot;fmt&quot;

type BankAccount struct {
	AccountNumber string
	AccountHolder string
	Balance       float64
	IsActive      bool
}

func (acc BankAccount) GetAccountInfo() string {
	status := &quot;active&quot;
	if !acc.IsActive {
		status = &quot;unactive&quot;
	}
	return fmt.Sprintf(&quot;账号:%s, 持有人:%s , 余额:%.3f, 状态: %s&quot;,
		acc.AccountNumber, acc.AccountHolder, acc.Balance, status)
}

func (acc *BankAccount) Deposit(amount float64) error {
	if !acc.IsActive {
		return fmt.Errorf(&quot;账号已冻结，无法存款&quot;)
	}

	if amount &amp;#x3C;= 0 {
		return fmt.Errorf(&quot;存款金额必须大于0&quot;)
	}
	acc.Balance += amount
	return nil
}

func (acc *BankAccount) Withdraw(amount float64) error {
	if !acc.IsActive {
		return fmt.Errorf(&quot;账号已冻结，无法取款&quot;)
	}
	if amount &amp;#x3C;= 0 {
		return fmt.Errorf(&quot;取款金额必须大于0&quot;)
	}
	if amount &gt; acc.Balance {
		return fmt.Errorf(&quot;取款金额不能大于余额&quot;)
	}
	acc.Balance -= amount
	return nil
}

func (acc *BankAccount) Freeze() {
	acc.IsActive = false
}

func (acc *BankAccount) Unfreeze() {
	acc.IsActive = true
}

func main() {
	acc := BankAccount{
		AccountNumber: &quot;654819854&quot;,
		AccountHolder: &quot;李四&quot;,
		IsActive:      true,
		Balance:       1000.0,
	}

	fmt.Println(acc.GetAccountInfo())

	if err := acc.Deposit(1000.0); err != nil {
		fmt.Println(&quot;存款失败&quot;, err)
	}
	fmt.Println(&quot;存款成功，余额:&quot;, acc.Balance)

	if err := acc.Withdraw(acc.Balance); err != nil {
		fmt.Println(&quot;取款失败&quot;, err)
	}
	fmt.Println(&quot;取款成功，余额:&quot;, acc.Balance)

	acc.Freeze()
	if err := acc.Deposit(500.0); err != nil {
		fmt.Println(&quot;存款失败&quot;, err)
	}

	acc.Unfreeze()
	if err := acc.Deposit(500.0); err != nil {
		fmt.Println(&quot;存款失败&quot;, err)
	}
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;接口&lt;/h2&gt;
&lt;p&gt;接口定义：&lt;/p&gt;
&lt;p&gt;接口为Go语言中实现多态的重要特性，它定义一组方法的签名，但不进行具体实现&lt;/p&gt;
&lt;p&gt;若一个类型实现了接口中的所有方法，则该类型实现了该接口，不需要显示声明&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;type 接口名 interface {
	方法1(参数列表) 返回值列表
	方法2(参数列表) 返回值列表
	...
}

//空接口
var x interface{} 
//空接口可以存储任意类型的值, 类似于Object(Java) any(Typescript)
x := &quot;Hello, World!&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;样例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

type Payment interface {
	Pay(amount float64) (string, error)
	Refund(trcID string, amount float64) (string, error)
	Query(trcID string) (string, error)
}

type AliPay struct {
	AppID      string
	AppSecret  string
	MerchantID string
}

func (acc AliPay) Pay(amount float64) (string, error) {
	return fmt.Sprintf(&quot;ALIPAY-%d&quot;, time.Now().Unix()), nil
}

func (acc AliPay) Refund(trcID string, amount float64) (string, error) {
	return fmt.Sprintf(&quot;ALIPAY_REFUND-%s&quot;, trcID), nil
}

func (acc AliPay) Query(trcID string) (string, error) {
	return &quot;交易成功&quot;, nil
}

type WechatPay struct {
	AppID      string
	AppSecret  string
	MerchantID string
}

func (acc WechatPay) Pay(amount float64) (string, error) {
	return fmt.Sprintf(&quot;WECHAT-%d&quot;, time.Now().Unix()), nil
}

func (acc WechatPay) Refund(trcID string, amount float64) (string, error) {
	return fmt.Sprintf(&quot;WECHAT_REFUND-%s&quot;, trcID), nil
}

func (acc WechatPay) Query(trcID string) (string, error) {
	return &quot;交易成功&quot;, nil
}

func ProcessPayment(pay Payment, amount float64) (string, error) {
	fmt.Println(&quot;开始处理支付请求...&quot;)
	trsID, err := pay.Pay(amount)
	if err != nil {
		return &quot;&quot;, err
	}
	fmt.Printf(&quot;支付成功, 交易号: %s\n&quot;, trsID)
	return trsID, nil
}

func main() {
	ali := AliPay{
		AppID:      &quot;alipay&quot;,
		AppSecret:  &quot;alisecret&quot;,
		MerchantID: &quot;ali_merchant&quot;,
	}

	wechat := WechatPay{
		AppID:      &quot;wechat&quot;,
		AppSecret:  &quot;wechatsecret&quot;,
		MerchantID: &quot;wedchat_merchant&quot;,
	}

	trs := []struct {
		Payment Payment
		Amount  float64
		Name    string
	}{
		{ali, 100, &quot;支付宝&quot;},
		{wechat, 100, &quot;微信&quot;},
	}

	for _, t := range trs {
		trID, err := ProcessPayment(t.Payment, t.Amount)
		if err != nil {
			fmt.Println(&quot;支付失败, 错误信息:&quot;, err)
		}
		fmt.Println(&quot;p: 支付成功, 交易号:&quot;, trID)
	}

	//空接口
	var x interface{}
	x = 123
	EmptyInterface(x)
	x = &quot;hello&quot;
	EmptyInterface(x)
}

func EmptyInterface(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Println(&quot;int:&quot;, v)
	case string:
		fmt.Println(&quot;string:&quot;, v)
	default:
		fmt.Println(&quot;unknown&quot;)
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Go面向对象&lt;/h2&gt;
&lt;p&gt;Go语言虽然不是传统意义上的面向对象语言，但它支持一些面向对象的特性，如结构体、方法和接口等。&lt;/p&gt;
&lt;p&gt;组合替代继承：Go语言不支持类的继承，但可以通过组合来实现类似的功能。通过将一个结构体嵌入到另一个结构体中，可以实现代码复用和行为扩展。&lt;/p&gt;
&lt;p&gt;样例1&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
	&quot;time&quot;
)

type BaseUser struct {
	ID        int64
	UserName  string
	Email     string
	CreatedAt time.Time
}

func (u BaseUser) GetCreateDate() string {
	return u.CreatedAt.Format(&quot;2006-01-02&quot;)
}

func (u *BaseUser) DisplayBasicInfo() {
	fmt.Printf(&quot;ID: %d Name: %s Email: %s CreateAt: %s&quot;, u.ID, u.UserName, u.Email, u.GetCreateDate())
}

type Address struct {
	Province string
	City     string
	Street   string
	Detail   string
}

func (a Address) GetFullAddress() string {
	return fmt.Sprintf(&quot;%s%s%s%s&quot;, a.Province, a.City, a.Street, a.Detail)
}

type NormalUser struct {
	BaseUser
	Address []Address
}

func (n *NormalUser) DisplayBasicInfo() {
	fmt.Printf(&quot;ID: %d Name: %s Email: %s&quot;, n.ID, n.UserName, n.Email)
}

func (n *NormalUser) AddAddress(address Address) {
	n.Address = append(n.Address, address)
}

type VIPUser struct {
	BaseUser
	Address    []Address
	VIPLevel   int
	Discount   float64
	ExpireTime time.Time
}

func (vu *VIPUser) AddAddress(address Address) {
	vu.Address = append(vu.Address, address)
}

func (vu *VIPUser) IsVipValid() bool {
	return vu.ExpireTime.After(time.Now())
}

func (vu *VIPUser) GetDiscount() float64 {
	if vu.IsVipValid() {
		return vu.Discount
	}
	return 1.0
}

type UserService struct {
}

const (
	UserTypeNormal = &quot;normal&quot;
	UserTypeVip    = &quot;vip&quot;
)

func getUserId() int64 {
	return time.Now().Unix()
}

func (s *UserService) CreateUser(username, email string, userType string) (interface{}, error) {
	baseUser := BaseUser{
		ID:        getUserId(),
		UserName:  username,
		Email:     email,
		CreatedAt: time.Now(),
	}

	switch userType {
	case UserTypeNormal:
		normalUser := NormalUser{
			BaseUser: baseUser,
			Address:  []Address{},
		}
		return normalUser, nil
	case UserTypeVip:
		vipUser := VIPUser{
			BaseUser:   baseUser,
			VIPLevel:   1,
			Discount:   0.9,
			ExpireTime: time.Now().AddDate(0, 0, 30),
		}
		return vipUser, nil
	default:
		return 0, fmt.Errorf(&quot;unknown user type: %s&quot;, userType)
	}
}

func main() {
	ser := &amp;#x26;UserService{}
	normalUser, err := ser.CreateUser(&quot;张三&quot;, &quot;zhangsan@example.com&quot;, UserTypeNormal)
	if err != nil {
		fmt.Println(&quot;normalUsr: &quot;, err)
		return
	}

	vipUser, err := ser.CreateUser(&quot;李四&quot;, &quot;lisi@example.com&quot;, UserTypeVip)
	if err != nil {
		fmt.Println(&quot;vipUsr: &quot;, err)
		return
	}

	nUser := normalUser.(NormalUser)
	nUser.AddAddress(Address{
		Province: &quot;四川省&quot;,
		City:     &quot;成都市&quot;,
		Street:   &quot;物流大道&quot;,
		Detail:   &quot;物流大道666号&quot;,
	})
	nUser.DisplayBasicInfo()

	users := []interface{}{nUser, vipUser}
	for _, user := range users {
		switch u := user.(type) {
		case NormalUser:
			fmt.Println(&quot;普通用户&quot;)
			fmt.Println(&quot;用户ID:&quot;, u.ID)
			fmt.Println(&quot;用户名:&quot;, u.UserName)
			fmt.Println(&quot;邮箱:&quot;, u.Email)
			fmt.Println(&quot;创建时间:&quot;, u.GetCreateDate())
			fmt.Println(&quot;地址:&quot;)
			for _, addr := range u.Address {
				fmt.Println(&quot; -&quot;, addr.GetFullAddress())
			}
		case VIPUser:
			fmt.Println(&quot;普通用户&quot;)
			fmt.Println(&quot;用户ID:&quot;, u.ID)
			fmt.Println(&quot;用户名:&quot;, u.UserName)
			fmt.Println(&quot;邮箱:&quot;, u.Email)
			fmt.Println(&quot;创建时间:&quot;, u.GetCreateDate())
			fmt.Println(&quot;VIP等级:&quot;, u.VIPLevel)
			fmt.Println(&quot;折扣:&quot;, u.Discount)
			fmt.Println(&quot;VIP状态:&quot;, u.IsVipValid())
			fmt.Println(&quot;地址:&quot;)
			for _, addr := range u.Address {
				addr.GetFullAddress()
			}
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;样例2：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main

import (
	&quot;fmt&quot;
)

type Notifier interface {
	Notify(message string) error
}

type EmailNotifier struct {
	SMTPHost string
	Port     string
}

func (e *EmailNotifier) Notify(message string) error {
	fmt.Printf(&quot;发送邮件成功: %s\n&quot;, message)
	return nil
}

type SmsNotifier struct {
	APIKey   string
	TmplCode string
}

func (s *SmsNotifier) Notify(message string) error {
	fmt.Printf(&quot;发送短信成功：: %s\n&quot;, message)
	return nil
}

type BroadCastNotifier struct {
	notifierList []Notifier
}

func (b *BroadCastNotifier) Notify(message string) error {
	for _, n := range b.notifierList {
		if err := n.Notify(message); nil != err {
			return err
		}
	}
	return nil
}

type OrderService struct {
	notifier Notifier
}

func (o *OrderService) SetNotify(n Notifier) {
	o.notifier = n
}

func (o *OrderService) CreateOrder(product string, quantity int) {
	fmt.Printf(&quot;创建订单：%s x %d \n&quot;, product, quantity)

	if err := o.notifier.Notify(&quot;订单已创建&quot;); err != nil {
		fmt.Println(err)
	}
}

func main() {
	orderService := &amp;#x26;OrderService{}

	emailNotifier := &amp;#x26;EmailNotifier{
		SMTPHost: &quot;smtp.163.com&quot;,
		Port:     &quot;465&quot;,
	}
	smsNotifier := &amp;#x26;SmsNotifier{
		APIKey:   &quot;asgdhjghkjfxbanuie_jlkdfsla&quot;,
		TmplCode: &quot;hjklncxsaoiuiw&quot;,
	}
	broadCastNotifier := &amp;#x26;BroadCastNotifier{
		notifierList: []Notifier{emailNotifier, smsNotifier},
	}

	orderService.SetNotify(emailNotifier)
	orderService.CreateOrder(&quot;邮件&quot;, 1)

	orderService.SetNotify(smsNotifier)
	orderService.CreateOrder(&quot;手机&quot;, 2)

	orderService.SetNotify(broadCastNotifier)
	orderService.CreateOrder(&quot;手机-邮件&quot;, 3)
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;包与包的导入&lt;/h2&gt;
&lt;p&gt;每个go源文件都必须属于一个包，声明在第一行&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;package main //main包是一个特殊的包，它定义了一个独立可执行的程序，而不是一个库。main包必须包含一个名为main的函数，作为程序的入口点。
package mypackage //自定义包，通常用于组织代码和实现模块化。包名通常与目录名相同，便于管理和导入。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;包导入机制:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;import (
	&quot;标准包名&quot;
	&quot;第三方包&quot;
	&quot;项目内部包&quot;
	&quot;自定义包&quot;
)

//也可以使用单个导入语句导入一个包
import &quot;fmt&quot;
import &quot;github.com/gin-gonic/gin&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;既然提到包的导入，就不得不提包的可见性了：
- 首字母大写的标识符是导出的，可以在包外部访问。
- 首字母小写的标识符是未导出的，只能在包内部访问。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;go常用标准库：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fmt：格式化输入输出&lt;/li&gt;
&lt;li&gt;os：操作系统功能&lt;/li&gt;
&lt;li&gt;io：输入输出操作&lt;/li&gt;
&lt;li&gt;net/http：HTTP客户端和服务器&lt;/li&gt;
&lt;li&gt;encoding/json：JSON编码和解码&lt;/li&gt;
&lt;li&gt;time：时间和日期处理&lt;/li&gt;
&lt;li&gt;math/rand：随机数生成&lt;/li&gt;
&lt;li&gt;strings：字符串操作&lt;/li&gt;
&lt;li&gt;strconv：字符串与基本数据类型转换&lt;/li&gt;
&lt;li&gt;$\cdots \cdots \cdots$&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;若需要其他标准库可查询官方文档&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;样例：&lt;/p&gt;
&lt;h2&gt;反射&lt;/h2&gt;
&lt;p&gt;定义：程序在运行时检查其自身的结构和行为的能力。&lt;/p&gt;
&lt;p&gt;核心：&lt;code&gt;interface{}&lt;/code&gt; + &lt;code&gt;reflect&lt;/code&gt;包&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-go&quot;&gt;var x int = 42
// 类型信息
t := reflect.TypeOf(x)

// 值信息
v := reflect.ValueOf(x)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Go工具链&lt;/h2&gt;
&lt;p&gt;Go工具链是Go语言提供的一组命令行工具，用于构建、测试、安装和管理Go代码。常用的Go工具链包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;go mod&lt;/strong&gt;: Go模块依赖管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go build&lt;/strong&gt;: 编译程序生成可执行文件&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go run&lt;/strong&gt;: 编译直接运行Go程序&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go test&lt;/strong&gt;: 运行测试，支持单元测试、示例测试和基准测试。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go fmt&lt;/strong&gt;: 格式化代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go get&lt;/strong&gt;: 添加依赖包到模块&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go install&lt;/strong&gt;: 编译并安装包或命令&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go vet&lt;/strong&gt;: 静态分析工具，检查代码中的潜在问题&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;go doc&lt;/strong&gt;: 查看文档&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;调试、分析工具(pprof,日志库)&lt;/h2&gt;
&lt;p&gt;Go提供了强大的调试和性能分析工具:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Delve调试器&lt;/strong&gt;: Go语言专用的调试器,支持断点、单步执行、变量查看等功能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pprof性能分析&lt;/strong&gt;: Go内置的性能分析工具,用于分析CPU和内存使用情况,帮助开发者优化程序性能&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;日志库&lt;/strong&gt;: Go标准库提供了基本的日志功能(log包),同时也有第三方日志库(如logrus、zap等)提供更丰富的日志功能和性能优化&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;内置工具&lt;/strong&gt;: racedetector, benchmark&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/golang.CC2e5hUs.png"/><enclosure url="/_astro/golang.CC2e5hUs.png"/></item><item><title>四川省大学生程序设计竞赛2026个人题解</title><link>https://santisify.top/blog/other/sccpc2026</link><guid isPermaLink="true">https://santisify.top/blog/other/sccpc2026</guid><description>因为退队原因，该题解为个人补题所写的</description><pubDate>Mon, 08 Jun 2026 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import {Collapse, Aside} from &apos;astro-pure/user&apos;;&lt;/p&gt;
&lt;h2&gt;最大权独立集问题&lt;/h2&gt;
&lt;p&gt;给定 $n$ 个点，每个点有一个整数权值 $W_i$。&lt;/p&gt;
&lt;p&gt;定义两点 $i$ 和 $j$ 之间存在一条无向边，当且仅当 $W_i \oplus W_j$（其中 $\oplus$ 表示按位异或运算）的二进制表示中，$1$ 的个数为奇数。&lt;/p&gt;
&lt;p&gt;请你求出这个图的最大权独立集。即，选择一个点集满足集合内任意两点之间没有边，且集合内点的权值之和最大。定义空集的权值为 $0$。你只需要求出这个最大的权值之和。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;本题有多组数据。&lt;/p&gt;
&lt;p&gt;输入一行一个正整数 $t$（$1 \le t \le 10^5$），表示测试数据组数。&lt;/p&gt;
&lt;p&gt;每组数据中：&lt;/p&gt;
&lt;p&gt;第一行一个正整数 $n$（$1 \le n \le 5 \times 10^5$），表示点数。&lt;/p&gt;
&lt;p&gt;第二行 $n$ 个正整数 $W_1,W_2,\cdots,W_n$（$1 \le W_i \le 10^9$），表示点的权值。&lt;/p&gt;
&lt;p&gt;保证 $1 \le \sum n \le 5 \times 10^5$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输出格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每组数据输出一行一个整数，表示最大权独立集的权值之和。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入输出样例 #1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3
5
3 5 15 1 2
3
6 7 11
4
1 2 4 8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输出 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;23
18
15
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;题目中给出$W_i$ 和 $W_j$二进制下异或结果的$1$个数为奇数代表之间有一条边.那我们可以假设一下,将数组$A$中的数按照二进制下 $1$ 的个数划分为奇数$X$和偶数$Y$两个集合.&lt;/p&gt;
&lt;p&gt;对于一个集合中两个数$X_i$($x$个$1$), $X_j$($y$个$1$), 其中两个数二进制下有$k$个$1$是同时出现的,那么这两个数异或后的结果就有$x+y-2*k$个$1$&lt;/p&gt;
&lt;p&gt;通过$x+y-2*k$可以发现无论$x$, $y$同为奇数或偶数结果都为偶数,可以证明同一个集合内的任意两个数不会有边.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    int a = 0, b = 0;
    for (int x, i = 0; i &amp;#x3C; n; ++i) {
        std::cin &gt;&gt; x;
        int ct = __builtin_popcount(x); //__builtin_popcount(x) 为计算x在二进制下1的个数
        if (ct &amp;#x26; 1) a += x;
        else b += x;
    }
    std::cout &amp;#x3C;&amp;#x3C; std::max(a, b) &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;那一天的回文字符串&lt;/h2&gt;
&lt;p&gt;一天，面码和仁太遇到了一个由小写英文字母组成的字符串 $s$。&lt;/p&gt;
&lt;p&gt;为了打发时间，他们发明了一个游戏：面码可以任意重排字符串中所有奇数下标位置上的字符，仁太可以任意重排字符串中所有偶数下标位置上的字符。&lt;/p&gt;
&lt;p&gt;他们想知道，经过这样的重排后，是否可以把字符串变成一个回文串。请你帮助他们！&lt;/p&gt;
&lt;p&gt;回文串指从前往后读和从后往前读都相同的字符串。例如，$\mathtt{aa}$、$\mathtt{aba}$ 和 $\mathtt{abccba}$ 是回文串，而 $\mathtt{sccpc}$、$\mathtt{reality}$ 和 $\mathtt{ab}$ 不是回文串。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第一行包含一个整数 $t$（$1 \le t \le 100$），表示测试数据的组数。&lt;/p&gt;
&lt;p&gt;对于每组测试数据，唯一一行包含一个由小写英文字母组成的字符串 $s$（$1 \le |s| \le 100$）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输出格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于每组测试数据，如果可以将 $s$ 变成回文串，输出一行 &quot;YES&quot;，否则输出一行 &quot;NO&quot;。&lt;/p&gt;
&lt;p&gt;你可以以任意大小写形式输出答案。例如，&quot;yEs&quot;、&quot;yes&quot;、&quot;Yes&quot; 和 &quot;YES&quot; 都会被视为正确回答。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入输出样例 #1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5
abba
abcd
aabb
abcba
abcde
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输出 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;YES
NO
YES
YES
NO
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;说明/提示&lt;/p&gt;
&lt;p&gt;在第一组测试数据中，给定字符串本身已经是一个回文串。&lt;/p&gt;
&lt;p&gt;在第三组测试数据中，可以重排奇数下标位置，使得下标 $1$ 处为 $\mathtt{a}$，下标 $3$ 处为 $\mathtt{b}$；同时重排偶数下标位置，使得下标 $2$ 处为 $\mathtt{b}$，下标 $4$ 处为 $\mathtt{a}$。这样可以得到回文串 $\mathtt{abba}$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;字符串中只能同奇偶性的下标的字母可交换,那么我们就需要根据字符串长度做分类讨论:&lt;/p&gt;
&lt;p&gt;1.对于偶数长度的字符串,只有偶数下标与奇数下标的字母完全相等才能组成回文字符串.&lt;/p&gt;
&lt;p&gt;2.对于奇数长度的字符串,只有不成对出现的个数$ct \le 1$才能组成回文字符串.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    std::vector&amp;#x3C;int&gt; a(30, 0), b(30, 0);
    for (int i = 0; i &amp;#x3C; s.size(); i ++) {
        if (i &amp;#x26; 1) b[s[i] - &apos;a&apos;] ++;
        else a[s[i] - &apos;a&apos;] ++;
    }
    bool res = false;
    if (s.size() &amp;#x26; 1) {
        int t1 = 0, t2 = 0;
        for (int i = 0; i &amp;#x3C; 26; i ++) {
            t1 += (a[i] &amp;#x26; 1);
            t2 += (b[i] &amp;#x26; 1);
        }
        res = (t1 + t2 &amp;#x3C;= 1);
    } else {
        res = (a == b);
    }
    std::cout &amp;#x3C;&amp;#x3C; (res ? &quot;YES&quot; : &quot;NO&quot;) &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;禁忌教典的消失咒文&lt;/h2&gt;
&lt;p&gt;阿尔扎诺帝国魔术学院中，格伦老师难得认真地研究起了一本古老的禁忌教典。教典中记载了一种特殊的法术序列。序列由 $n$ 道咒文组成，第 $i$ 道咒文的魔力值为 $a_i$。&lt;/p&gt;
&lt;p&gt;一开始，希丝缇娜以为只要把所有咒文的魔力简单相加，就能得到整个法术的强度。但格伦老师很快发现，这种咒文并不是这样运作的。第一道咒文会正向释放魔力，第二道咒文会反向抵消魔力，第三道咒文又会正向释放魔力，第四道咒文再次反向抵消魔力，之后依次交替。形式化地，对于一个法术序列 $b_1,b_2,...,b_m$，定义它的能量值为 $E(b)=\sum_{i=1}^{m}(-1)^{i+1}b_i$。空序列的能量值定义为 $0$。&lt;/p&gt;
&lt;p&gt;在继续解析教典时，露米娅发现其中有一段连续咒文受到了异常魔力污染。如果直接吟唱，整个法术很可能会失控。于是格伦老师决定：必须恰好选择一段非空连续咒文，将它们从序列中抹去。也就是说，需要选择一个区间 $[l,r]$，删除 $a_l,a_{l+1},...,a_r$。被删除的咒文消失后，剩余咒文会按照原来的相对顺序自动连接成一个新的法术序列 $a_1,...,a_{l-1},a_{r+1},...,a_n$。&lt;/p&gt;
&lt;p&gt;格伦老师希望最终得到的法术序列能量值恰好等于 $k$。请你帮助希丝缇娜和露米娅计算，有多少种不同的删除区间 $[l,r]$ 可以满足这个要求。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;第一行包含一个整数 $t$ ($1 \le t \le 10^5$)，表示测试数据组数。&lt;/p&gt;
&lt;p&gt;对于每组测试数据，第一行包含两个整数 $n,k$ ($1 \le n \le 10^6$，$-10^9 \le k \le 10^9$)，表示咒文数量和目标能量值。&lt;/p&gt;
&lt;p&gt;第二行包含 $n$ 个整数 $a_1,a_2,\ldots,a_n$ ($-10^9 \le a_i \le 10^9$)，表示每道咒文的魔力值。&lt;/p&gt;
&lt;p&gt;保证所有测试数据的 $n$ 之和不超过 $10^6$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输出格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;对于每组测试数据，输出一个整数，表示满足要求的删除区间数量。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入输出样例 #1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3
4 0
1 3 2 4
3 0
1 2 1
5 1
2 1 3 4 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输出 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2
2
3
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;这道题的核心在于将原序列的交替符号特性吸收到前缀和中，然后通过分析删除区间长度奇偶性对剩余序列能量值的影响，把问题转化为对前缀和的等式计数。&lt;/p&gt;
&lt;p&gt;记前缀和 $S_i = \sum_{j=1}^i A_j$。&lt;/p&gt;
&lt;p&gt;删除区间 $[l, r]$，剩余部分由 $[1, l-1]$ 和 $[r+1, n]$ 拼接而成。前半部分能量为 $S_{l-1}$。
后半部分的元素在原序列中位置前移了 $\text{len} = r-l+1$ 位。由于符号与位置的奇偶相关，移动 $\text{len}$ 位会导致后半部分每个元素的符号整体乘上 $(-1)^{\text{len}}$。因此后半部分能量为 $(-1)^{\text{len}} (S_n - S_r)$。
剩余序列总能量：
$$E = S_{l-1} + (-1)^{r-l+1}(S_n - S_r)$$
要求 $E = k$。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;若区间长度为偶数&lt;/strong&gt;（$r-l+1$ 为偶，即 $r$ 与 $l-1$ 同奇偶）：
$E = S_{l-1} + S_n - S_r = k \quad \Rightarrow \quad S_r = S_{l-1} + S_n - k$&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;若区间长度为奇数&lt;/strong&gt;（$r-l+1$ 为奇，即 $r$ 与 $l-1$ 不同奇偶）：
$E = S_{l-1} - (S_n - S_r) = k \quad \Rightarrow \quad S_r = k + S_n - S_{l-1}$&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;设 $x = l-1$，则 $0 \le x &amp;#x3C; r \le n$。对于确定的右端点 $r$，需要找满足等式的 $x$。利用 $x$ 与 $r$ 的奇偶关系，等式化为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同奇偶时：$S_x = S_r - S_n + k$ （记为 $v_1$）&lt;/li&gt;
&lt;li&gt;不同奇偶时：$S_x = S_n - S_r + k$ （记为 $v_2$）&lt;/li&gt;
&lt;li&gt;不同奇偶时：$S_x = S_n - S_r + k$ （记为 $v_2$）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们可以遍历右端点 $r = 1 \dots n$，用两个哈希表分别维护已遍历的、&lt;strong&gt;下标为偶数&lt;/strong&gt;的 $S_x$ 和&lt;strong&gt;下标为奇数&lt;/strong&gt;的 $S_x$ 的出现次数。对于当前 $r$：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若 $r$ 为奇数：同奇偶的 $x$ 必为奇数，查奇数表找 $v_1$；不同奇偶的 $x$ 为偶数，查偶数表找 $v_2$。&lt;/li&gt;
&lt;li&gt;若 $r$ 为偶数：同奇偶的 $x$ 为偶数，查偶数表找 $v_1$；不同奇偶的 $x$ 为奇数，查奇数表找 $v_2$。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;查询后，再将 $S_r$ 按 $r$ 的奇偶性存入对应的哈希表（这样保证只匹配 $x &amp;#x3C; r$）。最后累加结果。&lt;/p&gt;
&lt;p&gt;初始时 $x=0$（对应 $l=1$）是偶数且 $S_0=0$，因此将 &lt;code&gt;ct0[0]&lt;/code&gt; 初始化为 1。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n + 1, 0);
    for (int i = 1; i &amp;#x3C;= n; i ++) {
        std::cin &gt;&gt; a[i];
        if (i % 2 == 0) a[i] = -a[i];
    }
    for (int i = 1; i &amp;#x3C;= n; i ++) a[i] += a[i - 1];

    std::unordered_map&amp;#x3C;int, int&gt; ct0, ct1;
    int ans = 0;
    ct0[0] ++;
    for (int i = 1; i &amp;#x3C;= n; i ++) {
        int v1 = k + a[i] - a[n];
        int v2 = k - a[i] + a[n];
        if (i &amp;#x26; 1) {
            ans += ct0[v2] + ct1[v1];
        } else {
            ans += ct0[v1] + ct1[v2];
        }
        if (i &amp;#x26; 1) ct1[a[i]] ++;
        else ct0[a[i]] ++;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;永恒的奥古斯都&lt;/h2&gt;
&lt;p&gt;有一棵 $n$ 个点的树 $T$，树的根节点为 $1$。初始时点 $i$ 有颜色 $c_i$（$0 \le c_i \le 1$）。&lt;/p&gt;
&lt;p&gt;小 L 进行了若干次（可以为 $0$）操作，每次操作她会选择一个满足 $c_u =0$ 的节点 $u$，对 $u$ 子树内的所有点 $v$ 执行 $c_v \gets 1 - c_v$。所有操作结束后得到树 $T&apos;$，其中点 $i$ 的颜色变为了 $c&apos;_i$。&lt;/p&gt;
&lt;p&gt;现在给你最后得到的树 $T&apos;$ 和每个点的颜色 $c&apos;_i$，你需要求出有多少种不同的可能初始状态 $T$。答案对 $998244353$ 取模。&lt;/p&gt;
&lt;p&gt;在此题中，我们认为两棵树 $T_1,T_2$ 不同，当且仅当存在点 $1 \le u \le n$，满足其在 $T_1$ 中的颜色为 $c_{1,u}$，在 $T_2$ 中的颜色为 $c_{2,u}$，且 $c_{1,u} \neq c_{2,u}$。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;输入第一行一个正整数 $n$（$1 \le n \le 2 \times 10^5$），表示 $T&apos;$ 的点数。&lt;/p&gt;
&lt;p&gt;第二行 $n$ 个整数 $c&apos;_1,c&apos;_2,\cdots,c&apos;_n$（$0 \le c&apos;_i \le 1$），表示最终状态下每个点的颜色。&lt;/p&gt;
&lt;p&gt;接下来 $n-1$ 行，每行两个正整数 $u,v$（$1 \le u,v \le n$，$u \neq v$），表示 $T&apos;$ 中存在一条边 $(u,v)$。保证所有边构成一棵树。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输出格式&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;输出一行一个整数，表示可能的初始状态 $T$ 的个数对 $998244353$ 取模后的值。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入输出样例 #1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;3
0 0 1
1 2
1 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输出 #1&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输入输出样例 #2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;输入 #2&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;5
1 0 0 1 1
1 2
1 3
2 4
2 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;输出 #2&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;20
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;题目要求：给定最终树 &lt;code&gt;T&apos;&lt;/code&gt; 每个点的颜色 $c&apos;_i$（0/1）和树的结构，问有多少种可能的初始颜色状态 $c_i$，使得可以通过若干次“选择颜色为 0 的节点并翻转其子树”的操作变成 &lt;code&gt;c&apos;&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;设变量 $x_u ∈ {0, 1}$ 表示节点 &lt;code&gt;u&lt;/code&gt; 是否被操作（奇偶性）。最终颜色与初始颜色、操作的关系为：
$c&apos;_u = c_u \oplus x_v$ ( &lt;code&gt;v&lt;/code&gt; 是 &lt;code&gt;u&lt;/code&gt; 的祖先)
已知 &lt;code&gt;c&apos;&lt;/code&gt;，计数初始 &lt;code&gt;c&lt;/code&gt; 等价于计数合法的操作变量 &lt;code&gt;x&lt;/code&gt;（两者一一对应）。合法指存在一个操作顺序，使得每次操作时该节点当前颜色为 0。&lt;/p&gt;
&lt;p&gt;可以自底向上进行 DP，维护以 &lt;code&gt;u&lt;/code&gt; 为根的子树在两种情形下的合法初始状态数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;dp0[u]&lt;/code&gt;：&lt;code&gt;u&lt;/code&gt; &lt;strong&gt;不操作&lt;/strong&gt; ($x_u = 0$) 时子树内的方案数（实际上对于根，它包含了所有合法情况的答案）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dp1[u]&lt;/code&gt;：&lt;code&gt;u&lt;/code&gt; &lt;strong&gt;操作&lt;/strong&gt; ($x_u = 1$) 时子树内的方案数。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;核心结论&lt;/strong&gt;：若 &lt;code&gt;u&lt;/code&gt; 被操作，则其子树内所有初始颜色都可以通过合法操作达到目标，方案数达到最大，即
$$dp1[u] = 2^{\text{size}(u)}$$
其中 &lt;code&gt;size(u)&lt;/code&gt; 是以 &lt;code&gt;u&lt;/code&gt; 为根的子树大小。该值与 &lt;code&gt;c&apos;&lt;/code&gt; 无关，可以通过归纳证明。&lt;/p&gt;
&lt;p&gt;对 &lt;code&gt;u&lt;/code&gt; 的子节点 &lt;code&gt;v&lt;/code&gt;，设 $v1 = \prod dp0[v]$，$v2 = \prod dp1[v]$（代码中的记号）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;dp1[u]&lt;/code&gt;&lt;/strong&gt;：无论 &lt;code&gt;c&apos;_u&lt;/code&gt; 为何，&lt;code&gt;dp1[u] = 2 * v2&lt;/code&gt;。递归展开即 $2^{size(u)}$。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;dp0[u]&lt;/code&gt;&lt;/strong&gt;：根据 &lt;code&gt;c&apos;_u&lt;/code&gt; 分情况：&lt;/li&gt;
&lt;li&gt;若 $c&apos;_u = 0$：&lt;code&gt;u&lt;/code&gt; 必须不操作（否则最终颜色会变成 1），故 &lt;code&gt;dp0[u] = v1&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;若 $c&apos;_u = 1$：&lt;code&gt;u&lt;/code&gt; 可以不操作或操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不操作时贡献 &lt;code&gt;v1&lt;/code&gt;；操作时贡献 &lt;code&gt;v2&lt;/code&gt;（即 $2^{size(u)-1}$）。&lt;/p&gt;
&lt;p&gt;因此 &lt;code&gt;dp0[u] = v1 + v2&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;根节点 &lt;code&gt;1&lt;/code&gt; 没有父节点限制，所有合法方案均已包含在 &lt;code&gt;dp0[1]&lt;/code&gt; 中，直接输出即可。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

const int MOD = 998244353;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; c(n + 1, 0);
    std::vector g(n + 1, std::vector&amp;#x3C;int&gt;());
    for (int i = 1; i &amp;#x3C;= n; i ++) std::cin &gt;&gt; c[i];

    for (int i = 1, u, v; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; u &gt;&gt; v;
        g[u].push_back(v);
        g[v].push_back(u);
    }

    std::vector&amp;#x3C;int&gt; fa(n + 1, 0), vis(n + 1, 0), b;
    std::stack&amp;#x3C;int&gt; stk;
    stk.push(1);
    fa[1] = 0;
    while (!stk.empty()) {
        auto u = stk.top();
        if (!vis[u]) {
            vis[u] = 1;
            for (auto v: g[u]) {
                if (v != fa[u]) {
                    fa[v] = u;
                    stk.push(v);
                }
            }
        } else {
            stk.pop();
            b.push_back(u);
        }
    }

    std::vector&amp;#x3C;int&gt; dp0(n + 1, 0), dp1(n + 1, 0);
    for (auto u: b) {
        int v1 = 1, v2 = 1;
        for (auto v: g[u]) {
            if (v == fa[u]) continue;
            v1 = dp0[v] * v1 % MOD, v2 = dp1[v] * v2 % MOD;
        }

        dp0[u] = (v1 + c[u] * v2) % MOD;
        dp1[u] = (2 * v2) % MOD;
    }

    std::cout &amp;#x3C;&amp;#x3C; dp0[1] % MOD &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    // std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="undefined"/><enclosure url="undefined"/></item><item><title>ORM configuration(后续更新)</title><link>https://santisify.top/blog/other/orm</link><guid isPermaLink="true">https://santisify.top/blog/other/orm</guid><pubDate>Wed, 29 Apr 2026 22:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;nestjs + Mikro-ORM(v7)&lt;/h2&gt;
&lt;p&gt;当然首先是来安装&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pnpm add @mikro-orm/core @mikro-orm/nestjs @mikro-orm/mysql @mikro-orm/reflection
pnpm add tsx dotenv @mikro-orm/cli -D
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;CLI Configuration&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;.env.example&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;MIKRO_ORM_HOST=localhost
MIKRO_ORM_PORT=3306
MIKRO_ORM_USER=root
MIKRO_ORM_PASSWORD=123456
MIKRO_ORM_DB_NAME=demo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;mikro-orm.config.ts || src/mikro-orm.config.ts&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import &apos;dotenv/config&apos;;
import { defineConfig, MySqlDriver } from &apos;@mikro-orm/mysql&apos;;
import { TsMorphMetadataProvider } from &apos;@mikro-orm/reflection&apos;;

export default defineConfig({
  driver: MySqlDriver,
  dbName: process.env.MIKRO_ORM_DB_NAME,
  host: process.env.MIKRO_ORM_HOST,
  port: Number(process.env.MIKRO_ORM_PORT) ?? 3306,
  user: process.env.MIKRO_ORM_USER,
  password: process.env.MIKRO_ORM_PASSWORD,

  entities: [&apos;dist/**/*.entity.js&apos;],
  entitiesTs: [&apos;src/**/*.entity.ts&apos;],
  metadataProvider: TsMorphMetadataProvider,
  debug: true,
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Test CLI&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx mikro-orm debug
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行上述命令后会出现一些相关信息：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Current MikroORM CLI configuration
 - dependencies:
   - mikro-orm 7.0.11
   - node 24.13.0
   - typescript 5.9.3
 - package.json found
 - TypeScript support enabled (tsx)
 - searched config paths:
   - /home/santisify/code/webstorm/nestdemo/src/mikro-orm.config.ts (not found)
   - /home/santisify/code/webstorm/nestdemo/mikro-orm.config.ts (found)
   - /home/santisify/code/webstorm/nestdemo/dist/mikro-orm.config.js (not found)
   - /home/santisify/code/webstorm/nestdemo/mikro-orm.config.js (not found)
 - searched for config name: default
 - configuration found
 - driver dependencies:
   - kysely 0.28.16
   - mysql2 3.22.0
 - database connection successful
 - will use `entities` array (contains 0 references and 1 paths)
   - /home/santisify/code/webstorm/nestdemo/dist/**/*.entity.js (found)
 - could use `entitiesTs` array (contains 0 references and 1 paths)
   - /home/santisify/code/webstorm/nestdemo/src/**/*.entity.ts (found)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Database linkage&lt;/h3&gt;
&lt;p&gt;在对应的entity文件中添加装饰器(主键:&lt;code&gt;@PrimaryKey()&lt;/code&gt;， 其他：&lt;code&gt;@Property()&lt;/code&gt;)，可自动对字段进行类型推断，当然也可以自己设置(&lt;code&gt;@Property({type:&apos;text&apos;})&lt;/code&gt;),例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { Entity, PrimaryKey, Property } from &apos;@mikro-orm/decorators/legacy&apos;;

@Entity()
export class User {
  @PrimaryKey()
  id: number;

  @Property({ type:&apos;text&apos; })
  username: string;

  @Property()
  email: string;

  @Property()
  password: string;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以下代码为&lt;code&gt;mikro-orm&lt;/code&gt;创建迁移计划,并非修改数据库.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx mikro-orm migration:create
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行后你会得到一个全新的文件夹:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;./src/migrations/
├── Migration20260423123341.ts
└── .snapshot-nestdemo.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中文件&lt;code&gt;Migration20260423123341.ts&lt;/code&gt;, 数据库也会有相关的文件名记录,内容如下:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;import { Migration } from &apos;@mikro-orm/migrations&apos;;

export class Migration20260423123341 extends Migration {
  override up(): void | Promise&amp;#x3C;void&gt; {
    this.addSql(
      `create table \`user\` (\`id\` int unsigned not null auto_increment primary key, \`username\` varchar(255) not null, \`email\` varchar(255) not null, \`password\` varchar(255) not null) default character set utf8mb4 engine = InnoDB;`,
    );
  }

  override down(): void | Promise&amp;#x3C;void&gt; {
    this.addSql(`drop table if exists \`user\`;`);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;TIPS&lt;/strong&gt;:必记命令&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx mikro-orm migration:up  //迁移到最新版本,对应上方up函数
npx mikro-orm migration:down  //回退一个版本对应上方down函数
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;sequelize + nodejs + mysql&lt;/h2&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install sequelize mysql2
npm install @dotencx/dotenvx
npm install sequelize-cli -D   //喜欢使用cli的安装 cli文档链接：https://sequelize.org/docs/v7/cli/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Connection&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;databaseHelper.js&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import {Sequelize} from &apos;sequelize&apos;;

const databaseConfig = {
  username: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
}

export const sequelize = new Sequelize(
  databaseConfig.database,
  databaseConfig.username,
  databaseConfig.password,
  {
    host: databaseConfig.host,
    port: databaseConfig.port,
    dialect: &apos;mysql&apos;,
  }
);

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;.env.example&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;DB_NAME=nestdemo
DB_USER=root
DB_PASSWORD=123456
DB_HOST=localhost
DB_PORT=3306
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行&lt;code&gt;dotenvx run -- node databaseHelper.js&lt;/code&gt;测试连接是否成功。&lt;/p&gt;
&lt;p&gt;成功会显示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;⟐ injected env (5) from .env
Executing (default): SELECT 1+1 AS result
Connection has been established successfully.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;否则会报错:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Unable to connect to the database: AccessDeniedError [SequelizeAccessDeniedError]: Access denied for user &apos;root&apos;@&apos;localhost&apos; (using password: YES)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Define model&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;//../helpers/databaseHelper.js 为Connection中的js文件
import {sequelize} from &quot;../helpers/databaseHelper.js&quot;; 
import {DataTypes} from &quot;sequelize&quot;;

export const User = sequelize.define(
  &quot;User&quot;, //sequelize名称
  {//表字段
    id: {
      type: DataTypes.INTEGER,
      primaryKey: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
    }
  },
  {// createdAt和updatedAt 是sequlize默认加上的，若没有这两个字段可以设置false
    createdAt: false,
    updatedAt: false,
    tableName: &quot;users&quot;, //数据库表名
  }
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在测试文件中写入&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import {User} from &quot;./src/models/UserModel.js&quot;;

const users = await User.findAll();
console.log(users);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行&lt;code&gt;dotenvx run -- node test.js&lt;/code&gt;测试是否成功。
成功会显示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;⟐ injected env (5) from .env
Executing (default): SELECT `id`, `name`, `email`, `password` FROM `users` AS `User`;
[]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如没有数据表或者数据库表名填错，会在报错中找到:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  parent: Error: Table &apos;nestdemo.users&apos; doesn&apos;t exist
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;详细CRUD操作参考&lt;a href=&quot;https://sequelize.org/docs/v6/core-concepts/model-instances/&quot;&gt;sequelize文档&lt;/a&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/ORM.BH3_rrAQ.webp"/><enclosure url="/_astro/ORM.BH3_rrAQ.webp"/></item><item><title>codeforces 1095 (div3)</title><link>https://santisify.top/blog/codeforces/cf2227</link><guid isPermaLink="true">https://santisify.top/blog/codeforces/cf2227</guid><description>codeforces1095题解(A-F)</description><pubDate>Sun, 10 May 2026 14:33:38 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://codeforces.com/contest/2227/problems&quot;&gt;传送门&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;A. Koshary&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;在平面坐标系中两种移动方式向某个轴的正方向走 &lt;code&gt;1&lt;/code&gt; (最多一次)或者 &lt;code&gt;2&lt;/code&gt; 步.
问：能否从&lt;code&gt;(0,0)&lt;/code&gt;走到&lt;code&gt;(x, y)&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;因为最多走一次&lt;code&gt;1&lt;/code&gt;步,所以可以直接考虑&lt;code&gt;x&lt;/code&gt;和&lt;code&gt;y&lt;/code&gt;是否同时为奇数就可以判定了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int x, y;
    std::cin &gt;&gt; x &gt;&gt; y;
    std::cout &amp;#x3C;&amp;#x3C; ((x % 2 &amp;#x26;&amp;#x26; y % 2) ? &quot;NO&quot; : &quot;YES&quot;) &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B. Party Monster&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给出一个括号字符串,是否可以对这个字符串重新排列成一个合法的括号序列.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;既然是对字符串重新排列,那么只要有成对的&lt;code&gt;()&lt;/code&gt;就可以排列成合法的序列.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n;
    std::string s;
    std::cin &gt;&gt; n &gt;&gt; s;
    if (n &amp;#x26; 1) {
        std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; std::endl;
        return;
    }
    int ct1 = 0, ct2 = 0;
    for (int i = 0; i &amp;#x3C; n; i ++) {
        ct1 += (s[i] == &apos;(&apos;);
        ct2 += (s[i] == &apos;)&apos;);
    }

    std::cout &amp;#x3C;&amp;#x3C; (ct1 == ct2 ? &quot;YES&quot; : &quot;NO&quot;) &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C. Snowfall&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个数组,现在需要对数组进行排序,使得该数组中的子数组的乘积$\prod_{i=l}^{r}a_{i}(1\le l\le r\le n)$ 能被&lt;code&gt;6&lt;/code&gt;整除的子数组数量最少.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;被&lt;code&gt;6&lt;/code&gt;整除可以分为两种情况:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;$a_{i} % 6 = 0$,即$a_{i}$ 为&lt;code&gt;6&lt;/code&gt;的倍数&lt;/li&gt;
&lt;li&gt;$(a_{i} * a_{j}) % 6=0$,即$a_{i}$为&lt;code&gt;2&lt;/code&gt;的倍数($a_{j}$ 为&lt;code&gt;3&lt;/code&gt;的倍数)或者$a_{i}$为&lt;code&gt;3&lt;/code&gt;的倍数($a_{j}$ 为&lt;code&gt;2&lt;/code&gt;的倍数)
&gt;首先可以想到数组中能被&lt;code&gt;6&lt;/code&gt;整除的数随意放位置,那么就需要考虑能被&lt;code&gt;2&lt;/code&gt;和&lt;code&gt;3&lt;/code&gt;整除的数如何放了,很明显尽可能让&lt;code&gt;2&lt;/code&gt;和&lt;code&gt;3&lt;/code&gt;的倍数放在一起.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n);
    for (int i = 0; i &amp;#x3C; n; i ++) std::cin &gt;&gt; a[i];
    std::vector&amp;#x3C;int&gt; b, c, d, e;
    for (int i = 0; i &amp;#x3C; n; i ++) {
        if (a[i] % 6 == 0) b.push_back(a[i]);
        else if (a[i] % 3 == 0) e.push_back(a[i]);
        else if (a[i] % 2 == 0) c.push_back(a[i]);
        else d.push_back(a[i]);
    }

    for (auto i : b) {
        std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &quot; &quot;;
    }
    for (auto i : c) {
        std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &quot; &quot;;
    }
    for (auto i : d) {
        std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &quot; &quot;;
    }
    for (auto i : e) {
        std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &quot; &quot;;
    }
    std::cout &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D. Palindromex&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;一个长为&lt;code&gt;2n&lt;/code&gt;数组(数组中的数$x \in [0,n-1]$,并且每个数出现两次)中的所有回文数组的最大&lt;code&gt;mex&lt;/code&gt;
&lt;code&gt;mex&lt;/code&gt;:数组中不出现的最小非负整数.
回文数组:和回文字符串同理,将数组倒置和原数组一致.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;想要&lt;code&gt;mex&lt;/code&gt;最大,那一定包含数字&lt;code&gt;0&lt;/code&gt;,既然每个数都出现两次，那么我们就可以直接找到两个&lt;code&gt;0&lt;/code&gt;的位置，回文字符串要么包含其中一个&lt;code&gt;0&lt;/code&gt;，要么包含两个&lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;包含一个&lt;code&gt;0&lt;/code&gt;,直接向外拓展.&lt;/li&gt;
&lt;li&gt;包含两个&lt;code&gt;0&lt;/code&gt;,找到两个&lt;code&gt;0&lt;/code&gt;的中心点，向外拓展.
&gt;最后取这些情况的最大值即可.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n, p1 = -1, p2 = -1;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n * 2 + 1, 0);
    for (int i = 0; i &amp;#x3C; 2 * n; i ++) {
        std::cin &gt;&gt; a[i];
        if (a[i] == 0) {
            if (p2 == -1 &amp;#x26;&amp;#x26; p1 != -1) p2 = i;
            if (p1 == -1) p1 = i;
        }
    }

    auto mex = [&amp;#x26;](int l, int r) -&gt; int {
        std::vector&amp;#x3C;bool&gt; vis(2 * n + 1, false);
        for (int i = l; i &amp;#x3C;= r; i ++) vis[a[i]] = true;
        for (int i = 0; i &amp;#x3C;= n; i ++)
            if (!vis[i])
                return i;

        return 1;
    };

    auto extend = [&amp;#x26;](int x) -&gt; int {
        int l = x / 2, r = (x + 1) / 2;
        while (l &gt;= 0 &amp;#x26;&amp;#x26; r &amp;#x3C; 2 * n &amp;#x26;&amp;#x26; a[l] == a[r])
            l --, r ++;

        return mex(l + 1, r - 1);
    };

    std::cout &amp;#x3C;&amp;#x3C; std::max({extend(p1 + p2), extend(p1 * 2), extend(p2 * 2)}) &amp;#x3C;&amp;#x3C; std::endl;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;E. It All Went Sideways&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你一个由 nn 列方块组成的序列，第 ii 列初始有 aiai​ 个方块，竖直堆叠。在重力向右作用后，每块方块会尽量向右滑动，但不能穿过或重叠其他方块，且保持原来的高度。  你可以在重力变化前最多执行一次操作：选择某一列将其方块数减少 1（也可不操作）。&lt;/p&gt;
&lt;p&gt;定义“移动的方块”为重力变化后列编号发生变化的方块。&lt;/p&gt;
&lt;p&gt;问通过最优操作（或不操作），最多能让多少方块移动。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;重力向右后，方块保持高度尽量右移，最终第 &lt;code&gt;i&lt;/code&gt; 列的高度等于 $(\min_{j\ge i} a_j)$。&lt;/p&gt;
&lt;p&gt;定义数组 $mi[i] = min(a_{i}, \cdots, a_{n-1})$，即后缀最小值。&lt;/p&gt;
&lt;p&gt;初始总方块数 &lt;code&gt;S = sum(a)&lt;/code&gt;。不移动的方块数 = &lt;code&gt;sc = sum(mi)&lt;/code&gt;，因为每列最底部的 &lt;code&gt;mi[i]&lt;/code&gt; 个方块不会改变列编号。 原有移动数 = &lt;code&gt;S - sc&lt;/code&gt;。
只能将某一列减少 1，总方块数减 1，同时可能改变后缀最小值。&lt;/p&gt;
&lt;p&gt;减少操作的效果等价于：选择一个位置，把该列及其左侧所有列的 &lt;code&gt;mi&lt;/code&gt; 值可能降低（取决于是否突破原来的最小值）。&lt;/p&gt;
&lt;p&gt;最优操作是找 &lt;code&gt;mi&lt;/code&gt; 数组中&lt;strong&gt;连续相等的最长段&lt;/strong&gt;，将该段最左侧那一列减少 1。这样会让该段中每一列的不移动方块都减少 1，新增移动数 = 段长（&lt;code&gt;ma&lt;/code&gt;），但总方块数也少了 1，因此净增移动数为 &lt;code&gt;ma - 1&lt;/code&gt;。
$$ ans = (S - sc) + (ma - 1)$$
其中 &lt;code&gt;ma&lt;/code&gt; 是后缀最小值数组中最长连续相等段的长度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#define int long long
void solve() {
    int n, s = 0;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n + 1);
    for (int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i];
        s += a[i];
    }
    auto mi = a;
    for (int i = n - 2; i &gt;= 0; i --)
        mi[i] = std::min(mi[i], mi[i + 1]);

    int sc = std::accumulate(mi.begin(), mi.end(), 0ll);
    std::cerr &amp;#x3C;&amp;#x3C; s - sc &amp;#x3C;&amp;#x3C; std::endl;

    int ma = -1, cnt = 1;
    for (int i = 1; i &amp;#x3C; n; i ++) {
        if (mi[i] == mi[i - 1])
            cnt ++;
        else {
            ma = std::max(ma, cnt);
            cnt = 1;
        }
    }
    ma = std::max(ma, cnt);

    std::cout &amp;#x3C;&amp;#x3C; s - sc + ma - 1 &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;G.Drowning&lt;/h2&gt;
&lt;p&gt;思路及参考代码&lt;a href=&quot;https://blog.hailuo4ever.com/posts/contests/codeforces/round1096/#g---drowning&quot;&gt;Hailuo4ever&lt;/a&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/cf2227.wczNDBh1.webp"/><enclosure url="/_astro/cf2227.wczNDBh1.webp"/></item><item><title>sify-gist</title><link>https://santisify.top/blog/other/sifygist</link><guid isPermaLink="true">https://santisify.top/blog/other/sifygist</guid><description>Sify Gist: 打造属于你的代码片段分享平台</description><pubDate>Mon, 30 Mar 2026 20:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Sify Gist: 打造属于你的代码片段分享平台&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;在这个开源的时代，我们每天都在创造和积累代码。有没有想过拥有一个专属的代码宝库，既能安全存储，又能便捷分享？Sify Gist 应运而生。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;初识 Sify Gist&lt;/h2&gt;
&lt;p&gt;还记得 GitHub Gist 吗？那个让我们随手分享代码片段的神奇工具。&lt;strong&gt;Sify Gist&lt;/strong&gt; 正是受此启发，打造的一款现代化代码片段分享平台。它不仅继承了 Gist 的核心功能，更在此基础上进行了大量创新和优化。&lt;/p&gt;
&lt;p&gt;与传统的代码托管平台不同，Sify Gist 专注于&quot;小而美&quot;——它不求成为代码仓库的替代品，而是成为开发者日常工作流中的得力助手，让你能够：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快速记录和分享代码片段&lt;/li&gt;
&lt;li&gt;构建个人的代码知识库&lt;/li&gt;
&lt;li&gt;与团队成员共享常用工具代码&lt;/li&gt;
&lt;li&gt;沉淀和复用最佳实践&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;核心亮点&lt;/h2&gt;
&lt;h3&gt;🎯 三种可见性，灵活掌控&lt;/h3&gt;
&lt;p&gt;Sify Gist 提供三种可见性设置，满足不同场景需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;公开（Public）&lt;/strong&gt;：所有人可见，适合分享通用工具和教程代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;未列出（Unlisted）&lt;/strong&gt;：仅通过链接访问，适合团队内部共享&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;私有（Private）&lt;/strong&gt;：仅自己可见，适合存储敏感配置和个人笔记&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🌈 34+ 种语言支持，代码高亮更专业&lt;/h3&gt;
&lt;p&gt;支持 JavaScript、TypeScript、Python、Go、Rust、Java 等 34+ 种编程语言的语法高亮，使用业界领先的 Prism.js 渲染引擎，让代码展示清晰易读。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;多文件&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;✨ 强大的编辑体验&lt;/h3&gt;
&lt;p&gt;内置 &lt;strong&gt;Monaco Editor&lt;/strong&gt;（VS Code 的核心编辑器），提供：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;智能代码补全&lt;/li&gt;
&lt;li&gt;语法错误提示&lt;/li&gt;
&lt;li&gt;自动语言检测&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Markdown 实时预览&lt;/strong&gt; - 写文档不再需要切换窗口&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CSV 表格预览&lt;/strong&gt; - 数据文件一目了然&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🍴 Fork 功能，协作更简单&lt;/h3&gt;
&lt;p&gt;看到别人的好代码？一键 Fork 到自己账户，然后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在此基础上进行修改和优化&lt;/li&gt;
&lt;li&gt;追踪 Fork 来源，方便溯源&lt;/li&gt;
&lt;li&gt;构建 Fork 网络，促进社区协作&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;⭐ 收藏与标签，知识管理更高效&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;收藏功能&lt;/strong&gt;：将常用的 Gist 加入收藏夹，随时快速访问&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;标签系统&lt;/strong&gt;：为 Gist 添加多个标签，分类管理更清晰&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;发现页面&lt;/strong&gt;：浏览公开 Gist，发现热门标签，探索社区智慧&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🚀 一键嵌入，分享零门槛&lt;/h3&gt;
&lt;p&gt;独有的 &lt;strong&gt;Embed JS&lt;/strong&gt; 功能，让你可以像嵌入 YouTube 视频一样，将代码片段嵌入到任何网页：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;script src=&quot;https://your-domain.com/api/gists/abc123/embed.js&quot;&gt;&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;适合嵌入到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;技术博客文章&lt;/li&gt;
&lt;li&gt;项目文档站点&lt;/li&gt;
&lt;li&gt;团队知识库&lt;/li&gt;
&lt;li&gt;在线教程平台&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🔍 全文搜索，快速定位&lt;/h3&gt;
&lt;p&gt;强大的搜索功能支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题搜索&lt;/li&gt;
&lt;li&gt;描述搜索&lt;/li&gt;
&lt;li&gt;文件名搜索&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码内容搜索&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再多的代码片段，也能快速找到所需内容。&lt;/p&gt;
&lt;h2&gt;技术栈：现代、稳定、可扩展&lt;/h2&gt;
&lt;p&gt;Sify Gist 采用业界领先的技术栈构建：&lt;/p&gt;
&lt;p&gt;| 技术 | 用途 | 优势 |
|------|------|------|
| &lt;strong&gt;Next.js 14&lt;/strong&gt; | React 框架 | App Router、服务端渲染、极致性能 |
| &lt;strong&gt;TypeScript&lt;/strong&gt; | 类型系统 | 类型安全、开发体验更佳 |
| &lt;strong&gt;Tailwind CSS&lt;/strong&gt; | 样式方案 | 原子化 CSS、快速开发 |
| &lt;strong&gt;Supabase&lt;/strong&gt; | 数据库 | 开源、可扩展、实时同步 |
| &lt;strong&gt;Vercel&lt;/strong&gt; | 部署平台 | 边缘计算、自动扩容 |&lt;/p&gt;
&lt;h3&gt;为什么选择 Supabase？&lt;/h3&gt;
&lt;p&gt;Supabase 作为开源的 Firebase 替代品，提供了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全托管的 PostgreSQL 数据库&lt;/li&gt;
&lt;li&gt;行级安全策略（RLS）&lt;/li&gt;
&lt;li&gt;实时订阅功能&lt;/li&gt;
&lt;li&gt;存储桶服务（用于头像等文件）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最重要的是，它完美适配 Vercel 的无服务器环境，让整个架构保持简洁高效。&lt;/p&gt;
&lt;h2&gt;部署：一行命令，即刻上线&lt;/h2&gt;
&lt;h3&gt;方式一：一键部署到 Vercel&lt;/h3&gt;
&lt;p&gt;点击下方按钮，即可一键部署到 Vercel：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://vercel.com/new/clone?repository-url=https://github.com/santisify/sify-gist&quot;&gt;&lt;img src=&quot;https://vercel.com/button&quot; alt=&quot;Deploy with Vercel&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;方式二：手动部署&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 1. 克隆项目
git clone https://github.com/santisify/sify-gist.git
cd sify-gist

# 2. 安装依赖
npm install

# 3. 配置环境变量
# 创建 .env.local 文件，填入 Supabase 配置

# 4. 启动开发服务器
npm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整个过程不超过 5 分钟，你就能拥有一个完全属于自己的代码片段分享平台。&lt;/p&gt;
&lt;h2&gt;完整的 API 支持&lt;/h2&gt;
&lt;p&gt;Sify Gist 提供了完整的 RESTful API，方便你构建自定义客户端或集成到其他系统：&lt;/p&gt;
&lt;h3&gt;Gist 相关 API&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;GET    /api/gists              # 获取 Gist 列表
POST   /api/gists              # 创建新 Gist
GET    /api/gists/:id          # 获取 Gist 详情
PUT    /api/gists/:id          # 更新 Gist
DELETE /api/gists/:id          # 删除 Gist
POST   /api/gists/:id/fork     # Fork Gist
POST   /api/gists/:id/star     # 收藏 Gist
GET    /api/gists/:id/raw/:filename  # 获取原始文件
GET    /api/gists/:id/export   # 导出为 ZIP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完整的 API 文档可在应用内访问 &lt;code&gt;/api-docs&lt;/code&gt; 查看。&lt;/p&gt;
&lt;h2&gt;用户系统：安全可靠&lt;/h2&gt;
&lt;h3&gt;注册与登录&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;安全的密码加密存储（bcrypt）&lt;/li&gt;
&lt;li&gt;JWT 身份验证&lt;/li&gt;
&lt;li&gt;Token 自动刷新机制&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;个人中心&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自定义头像上传&lt;/li&gt;
&lt;li&gt;密码修改&lt;/li&gt;
&lt;li&gt;查看和管理所有 Gist&lt;/li&gt;
&lt;li&gt;查看收藏列表&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;用户公开主页&lt;/h3&gt;
&lt;p&gt;每个用户都有专属的公开主页，展示所有公开的 Gist，方便分享和展示。&lt;/p&gt;
&lt;h2&gt;响应式设计 + 深色模式&lt;/h2&gt;
&lt;h3&gt;全平台适配&lt;/h3&gt;
&lt;p&gt;无论是桌面端的大屏幕，还是移动端的小屏幕，Sify Gist 都能完美适配：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流畅的响应式布局&lt;/li&gt;
&lt;li&gt;触控友好的交互设计&lt;/li&gt;
&lt;li&gt;合理的信息密度调整&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;深色模式&lt;/h3&gt;
&lt;p&gt;内置深色模式支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动跟随系统偏好&lt;/li&gt;
&lt;li&gt;一键切换主题&lt;/li&gt;
&lt;li&gt;护眼配色方案&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;适用场景&lt;/h2&gt;
&lt;h3&gt;个人开发者&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;搭建个人代码知识库&lt;/li&gt;
&lt;li&gt;收藏常用的代码片段&lt;/li&gt;
&lt;li&gt;记录技术学习笔记&lt;/li&gt;
&lt;li&gt;分享技术博客中的示例代码&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;团队协作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;共享团队常用工具函数&lt;/li&gt;
&lt;li&gt;沉淀项目最佳实践&lt;/li&gt;
&lt;li&gt;快速分享调试代码&lt;/li&gt;
&lt;li&gt;新人入门代码示例库&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;教育培训&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;教师分享课程示例代码&lt;/li&gt;
&lt;li&gt;学生提交编程作业&lt;/li&gt;
&lt;li&gt;代码点评和讲解&lt;/li&gt;
&lt;li&gt;学习笔记整理&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;技术写作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;博客文章代码展示&lt;/li&gt;
&lt;li&gt;教程示例代码托管&lt;/li&gt;
&lt;li&gt;技术文档代码片段&lt;/li&gt;
&lt;li&gt;项目 Demo 演示&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;开源与社区&lt;/h2&gt;
&lt;p&gt;Sify Gist 是一个完全开源的项目，采用 MIT 许可证。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GitHub&lt;/strong&gt;：&lt;a href=&quot;https://github.com/santisify/sify-gist&quot;&gt;https://github.com/santisify/sify-gist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问题反馈&lt;/strong&gt;：欢迎提交 Issue&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;功能建议&lt;/strong&gt;：期待你的 Pull Request&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;致谢&lt;/h3&gt;
&lt;p&gt;本项目受到 &lt;a href=&quot;https://github.com/thomiceli/opengist&quot;&gt;OpenGist&lt;/a&gt; 的启发。OpenGist 是一个优秀的自托管 Pastebin 解决方案，使用 Git 驱动。如果你需要更完整的、支持 Git 同步和 OAuth 登录的自托管方案，推荐使用 OpenGist。&lt;/p&gt;
&lt;h2&gt;未来规划&lt;/h2&gt;
&lt;p&gt;Sify Gist 仍在持续迭代中，计划中的功能包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📋 Markdown 文件渲染&lt;/li&gt;
&lt;li&gt;🎨 代码主题自定义&lt;/li&gt;
&lt;li&gt;🌍 多语言国际化&lt;/li&gt;
&lt;li&gt;🔗 OAuth 第三方登录&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;立即体验&lt;/strong&gt;：&lt;a href=&quot;https://gist.santisify.top&quot;&gt;Demo 站点&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;项目地址&lt;/strong&gt;：&lt;a href=&quot;https://github.com/santisify/sify-gist&quot;&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;作者&lt;/strong&gt;：santisify&lt;/p&gt;</content:encoded><h:img src="/_astro/sifygist.DaNmK9pT.png"/><enclosure url="/_astro/sifygist.DaNmK9pT.png"/></item><item><title>MC服务端打包（由客户端推导）</title><link>https://santisify.top/blog/other/mc_clienttoserver</link><guid isPermaLink="true">https://santisify.top/blog/other/mc_clienttoserver</guid><description>还在为想玩的整合包无法开服而烦劳吗？不妨来看看这篇文章</description><pubDate>Wed, 25 Feb 2026 12:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;想要快速搭建Minecraft服务器却苦于繁琐的配置流程？ServerPackCreator正是您需要的解决方案。这款开源工具能够将Forge、Fabric、Quilt、LegacyFabric和NeoForge模组包一键转换为对应的服务器包，大幅简化服务器部署过程。&lt;/p&gt;
&lt;p&gt;无论您是模组开发者、服务器管理员还是普通玩家，都能通过这款工具轻松创建专业级的Minecraft服务器环境。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;为什么选择ServerPackCreator？&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;传统Minecraft服务器搭建需要手动处理大量配置文件和模组兼容性问题，而ServerPackCreator通过自动化流程彻底改变了这一现状。&lt;/p&gt;
&lt;p&gt;您不再需要逐个检查模组兼容性、手动配置启动参数或担心版本冲突问题。该工具支持主流模组加载器，能够智能识别并排除客户端专用模组，确保生成的服务器包既完整又稳定。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;快速上手&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ServerPackCreator&lt;/code&gt;官方提供了三种使用方法，当然我们选择最简单的GUI。&lt;/p&gt;
&lt;h3&gt;安装ServerPackCreator&lt;/h3&gt;
&lt;p&gt;首先我们需要下载安装包,以下为安装包列表链接.根据个人的操作系统进行选择.&lt;/p&gt;
&lt;p&gt;import { Card } from &apos;astro-pure/user&apos;&lt;/p&gt;
&lt;p&gt;&amp;#x3C;Card
as=&apos;a&apos;
href=&apos;https://github.com/Griefed/ServerPackCreator/releases&apos;
heading=&apos;Griefed/ServerPackCreator&apos;
subheading=&apos;Create a server pack from a Minecraft Forge, NeoForge, Fabric, LegacyFabric or Quilt modpack!&apos;&lt;/p&gt;
&lt;blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Click Me!!!
&lt;/p&gt;
&lt;p&gt;根据安装提示进行安装即可&lt;/p&gt;
&lt;h3&gt;服务端包制作&lt;/h3&gt;
&lt;p&gt;首先你需要使用MC启动器安装好需要打包的整合包的实例.
&lt;img src=&quot;./1.png&quot; alt=&quot;[1.png]&quot;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;选择需要打包的整合包。&lt;/li&gt;
&lt;li&gt;确认MC版本，模组加载器及版本。&lt;/li&gt;
&lt;li&gt;生成服务包。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;随即就会出现这个窗口,点击是就会跳转到对应的服务包
&lt;img src=&quot;./2.png&quot; alt=&quot;[2.png]&quot;&gt;&lt;/p&gt;
&lt;h3&gt;安装模组加载器服务端&lt;/h3&gt;
&lt;p&gt;我们需要到对应的模组加载器官网下载一个&lt;code&gt;.jar&lt;/code&gt;文件，我么需要使用这个&lt;code&gt;.jar&lt;/code&gt;文件构建服务端，此外我们也需要对应的java版本（可以去搜索一下）。
这里我以&lt;code&gt;neoforge&lt;/code&gt;为例
&lt;img src=&quot;./3.png&quot; alt=&quot;[3.png]&quot;&gt;&lt;/p&gt;
&lt;p&gt;下载后放在之前打包好的服务端文件夹中。如下图所示：
&lt;img src=&quot;./4.png&quot; alt=&quot;[4.png]&quot;&gt;
为了方便区分可以将上述图片中后缀为&lt;code&gt;.bat, .sh, .ps1&lt;/code&gt;的文件删掉。
现在需要下载服务端的包了，每个模组加载器的命令不一致需要参考加载器官方的使用文档。
打开终端执行命令，这个步骤需要保证安装了&lt;code&gt;java&lt;/code&gt;,终端打开打包好的服务端文件夹。执行一下命令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;java -jar ./neoforge-21.1.172-installer.jar --installServer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;需要将&lt;code&gt;neoforge-21.1.172-installer.jar&lt;/code&gt;换为自己对应的文件名称&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;执行完成后会发现有后缀为&lt;code&gt;sh&lt;/code&gt;或&lt;code&gt;bat&lt;/code&gt;的文件生成，现在新建一个文件命名为&lt;code&gt;eula.txt&lt;/code&gt;，至于有什么用可以自己查询下官方的解释，内容为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eula=true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你是&lt;code&gt;windows&lt;/code&gt;系统可以直接双击&lt;code&gt;.bat&lt;/code&gt;后缀的文件，&lt;code&gt;linux&lt;/code&gt;系统在终端执行&lt;em&gt;bash ./run.sh&lt;/em&gt;(run.sh 替换为实际名称)&lt;/p&gt;
&lt;h3&gt;问题解决&lt;/h3&gt;
&lt;p&gt;当然不可能是一帆风顺的，除非你运气好......
每个人的问题都千奇百怪，那么就需要ai来帮我们解决问题了，在文件中打开&lt;code&gt;logs&lt;/code&gt;将里面的&lt;code&gt;latest.log&lt;/code&gt;文件内容发给ai,具体哪种算是报错呢？下面是无问题页面
&lt;img src=&quot;./5.png&quot; alt=&quot;[5.png]&quot;&gt;
命令行底部有一个箭头或者有一个名称为&lt;code&gt;Minecreaft Server&lt;/code&gt;的窗口即为正确。&lt;/p&gt;
&lt;h2&gt;部署&lt;/h2&gt;
&lt;p&gt;选择合适的服务器，如果是新手可以尝试使用面板安装。
部署时只需要将无问题的服务端文件上传到服务器，最后执行上述生成的&lt;code&gt;run.sh&lt;/code&gt;或&lt;code&gt;run.bat&lt;/code&gt;文件即可。最后配置一下端口即可。&lt;/p&gt;</content:encoded><h:img src="/_astro/Mc_ClientToServer.C-eoCX38.jpg"/><enclosure url="/_astro/Mc_ClientToServer.C-eoCX38.jpg"/></item><item><title>2025年度报告</title><link>https://santisify.top/blog/other/2025-report</link><guid isPermaLink="true">https://santisify.top/blog/other/2025-report</guid><description>2025年个人成长与技术发展回顾</description><pubDate>Wed, 31 Dec 2025 23:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;2025年度报告&lt;/h1&gt;
&lt;p&gt;[toc]&lt;/p&gt;
&lt;p&gt;随着2025年的结束，我想回顾一下这一年的成长、挑战和收获。这一年充满了技术探索、个人发展和对未来方向的思考。&lt;/p&gt;
&lt;h2&gt;一、技术发展&lt;/h2&gt;
&lt;h3&gt;1.1 前端技术&lt;/h3&gt;
&lt;p&gt;2025年，我继续深入学习现代前端技术栈，特别是Astro框架的使用。通过构建和维护我的个人网站，我掌握了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Astro静态站点生成&lt;/li&gt;
&lt;li&gt;响应式设计和现代化UI组件&lt;/li&gt;
&lt;li&gt;性能优化技巧&lt;/li&gt;
&lt;li&gt;无障碍访问最佳实践&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.2 后端技术&lt;/h3&gt;
&lt;p&gt;在后端方面，我探索了多种技术：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js和相关框架&lt;/li&gt;
&lt;li&gt;数据库设计与优化&lt;/li&gt;
&lt;li&gt;API设计与开发&lt;/li&gt;
&lt;li&gt;微服务架构思想&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;1.3 工具与流程&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;版本控制：Git工作流程优化&lt;/li&gt;
&lt;li&gt;自动化部署：CI/CD实践&lt;/li&gt;
&lt;li&gt;代码质量：测试与代码审查&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二、项目成果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;优化了网站性能，减少了加载时间&lt;/li&gt;
&lt;li&gt;增强了内容管理系统&lt;/li&gt;
&lt;li&gt;改进了用户体验和可访问性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、学习与成长&lt;/h2&gt;
&lt;h3&gt;3.1 技术学习&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;深入学习了算法和数据结构&lt;/li&gt;
&lt;li&gt;研究了设计模式和架构原则&lt;/li&gt;
&lt;li&gt;探索了新技术趋势，如AI集成&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3.2 软技能提升&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;沟通技巧的改进&lt;/li&gt;
&lt;li&gt;团队协作能力&lt;/li&gt;
&lt;li&gt;项目管理经验&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、挑战与克服&lt;/h2&gt;
&lt;h3&gt;4.1 遇到的技术难题&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;性能优化挑战&lt;/li&gt;
&lt;li&gt;跨浏览器兼容性问题&lt;/li&gt;
&lt;li&gt;代码维护复杂性&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4.2 解决方案&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;通过系统性调试和分析解决复杂问题&lt;/li&gt;
&lt;li&gt;学习最佳实践并应用到项目中&lt;/li&gt;
&lt;li&gt;建立了更完善的测试流程&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;五、展望2026&lt;/h2&gt;
&lt;h3&gt;5.1 技术目标&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;深入学习AI和机器学习技术&lt;/li&gt;
&lt;li&gt;探索新的前端框架和工具&lt;/li&gt;
&lt;li&gt;提高系统架构设计能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.2 项目计划&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;开发更多实用的工具&lt;/li&gt;
&lt;li&gt;优化现有项目&lt;/li&gt;
&lt;li&gt;尝试新的项目类型&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5.3 个人发展&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;继续提升软技能&lt;/li&gt;
&lt;li&gt;扩展技术视野&lt;/li&gt;
&lt;li&gt;建立更广泛的行业联系&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;六、结语&lt;/h2&gt;
&lt;p&gt;2025年是充满挑战和机遇的一年。我学到了很多，成长了很多，也意识到还有很多需要学习和改进的地方。期待2026年能继续在技术道路上前行，创造更多有价值的东西。&lt;/p&gt;</content:encoded><h:img src="/_astro/2025-report.BcFk_lT_.webp"/><enclosure url="/_astro/2025-report.BcFk_lT_.webp"/></item><item><title>PixelPunk:一键部署你的私有文件管理平台</title><link>https://santisify.top/blog/other/pixelpunk</link><guid isPermaLink="true">https://santisify.top/blog/other/pixelpunk</guid><pubDate>Wed, 03 Dec 2025 15:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;📁 私有文件管理平台 PixelPunk&lt;/h1&gt;
&lt;h2&gt;✨ 项目简介&lt;/h2&gt;
&lt;p&gt;今天，我要向大家推荐一个令人惊艳的开源项目 —— &lt;strong&gt;PixelPunk&lt;/strong&gt;！
这是一个功能强大、设计优雅的私有文件管理与分享平台，集成了文件上传下载、AI 智能分析、向量搜索等多种现代功能。项目采用 Go 语言开发，性能出色、部署便捷，是搭建个人或团队私有云存储的理想选择。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🎯 为什么选择 PixelPunk？&lt;/h2&gt;
&lt;p&gt;| 特点         | 说明                                               |
| ------------ | -------------------------------------------------- |
| &lt;strong&gt;功能丰富&lt;/strong&gt; | 不止是文件存储，还集成 AI 分析、向量搜索等高级特性 |
| &lt;strong&gt;界面现代&lt;/strong&gt; | 简洁美观的前端设计，提供流畅的用户交互体验         |
| &lt;strong&gt;部署轻松&lt;/strong&gt; | 支持一键部署，快速搭建私有化环境                   |
| &lt;strong&gt;安全可靠&lt;/strong&gt; | 数据完全自主掌控，支持私有化部署，保障隐私安全     |
| &lt;strong&gt;扩展灵活&lt;/strong&gt; | 支持多种数据库、存储后端，便于按需定制             |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🏗️ 技术架构&lt;/h2&gt;
&lt;p&gt;PixelPunk 采用了前后端分离的现代化架构设计：&lt;/p&gt;
&lt;p&gt;| 组件           | 技术选型                                |
| -------------- | --------------------------------------- |
| &lt;strong&gt;后端服务&lt;/strong&gt;   | Go + Gin 框架                           |
| &lt;strong&gt;数据库&lt;/strong&gt;     | PostgreSQL / MySQL / SQLite（多选支持） |
| &lt;strong&gt;向量数据库&lt;/strong&gt; | Qdrant（用于 AI 向量搜索）              |
| &lt;strong&gt;前端界面&lt;/strong&gt;   | Vue 3 + Vite + TypeScript               |
| &lt;strong&gt;缓存服务&lt;/strong&gt;   | Redis                                   |
| &lt;strong&gt;文件存储&lt;/strong&gt;   | 本地存储 / 云存储（S3 兼容）            |&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🚀 一键部署体验&lt;/h2&gt;
&lt;p&gt;我亲自部署过，整个过程非常顺畅！只需执行以下命令，即可快速启动服务：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 使用在线脚本一键部署
curl -fsSL https://raw.githubusercontent.com/CooperJiang/PixelPunk/main/scripts/deploy/deploy.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者，也可以先克隆项目再手动部署：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/CooperJiang/PixelPunk.git
cd PixelPunk
bash scripts/deploy/deploy.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;部署脚本会自动完成以下工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;📦 拉取最新代码和依赖&lt;/li&gt;
&lt;li&gt;⚙️ 生成并配置环境变量&lt;/li&gt;
&lt;li&gt;🐳 启动数据库、缓存、向量库等服务&lt;/li&gt;
&lt;li&gt;🚀 运行前后端应用&lt;/li&gt;
&lt;li&gt;🗃️ 初始化数据库和索引&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完成后，访问 &lt;code&gt;http://localhost:8080&lt;/code&gt;（默认端口）即可进入平台。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;💡 提示：若需修改端口或配置域名，可在部署前调整环境变量。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;🧩 核心功能体验&lt;/h2&gt;
&lt;h3&gt;📂 文件管理&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;直观的树形文件浏览器&lt;/li&gt;
&lt;li&gt;拖拽上传、批量操作&lt;/li&gt;
&lt;li&gt;文件标签、分类管理&lt;/li&gt;
&lt;li&gt;版本控制与历史记录&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🤖 AI 智能分析&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;文件内容自动解析与摘要&lt;/li&gt;
&lt;li&gt;智能标签生成与分类&lt;/li&gt;
&lt;li&gt;图像内容识别（EXIF、场景识别）&lt;/li&gt;
&lt;li&gt;文档内容提取（PDF、Word、文本）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;🔍 向量搜索&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;基于 Qdrant 的语义向量搜索&lt;/li&gt;
&lt;li&gt;相似文件智能推荐&lt;/li&gt;
&lt;li&gt;多模态搜索（文本、图像混合检索）&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;📝 部署建议&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;服务器配置&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;最低推荐：2 核 CPU / 4 GB 内存&lt;/li&gt;
&lt;li&gt;生产环境建议：4 核 CPU / 8 GB 内存 或更高&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;strong&gt;域名与安全&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;建议绑定域名并配置 HTTPS（Let&apos;s Encrypt 免费证书）&lt;/li&gt;
&lt;li&gt;配置防火墙规则，限制不必要的端口访问&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;数据备份&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;定期备份数据库（可使用 pg_dump 或 mysqldump）&lt;/li&gt;
&lt;li&gt;文件存储目录建议同步至云存储或进行异地备份&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;&lt;strong&gt;性能调优&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;根据使用情况调整 Gin 的并发参数&lt;/li&gt;
&lt;li&gt;合理配置 Redis 缓存策略，提升响应速度&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;💭 使用心得&lt;/h2&gt;
&lt;p&gt;亲自体验下来，PixelPunk 给我留下了深刻印象：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;部署过程十分顺畅，几乎无门槛&lt;/li&gt;
&lt;li&gt;界面设计简洁而不失现代感，交互流畅&lt;/li&gt;
&lt;li&gt;AI 分析功能实用，能大幅提升文件管理效率&lt;/li&gt;
&lt;li&gt;向量搜索响应迅速，准确率高&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特别适合需要&lt;strong&gt;安全、私有、智能&lt;/strong&gt;的文件管理场景，如团队文档协作、个人知识库、多媒体资产管理等。&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;🎉 总结&lt;/h2&gt;
&lt;p&gt;如果你正在寻找一个&lt;strong&gt;功能全面、界面美观、部署简单&lt;/strong&gt;的私有文件管理平台，PixelPunk 绝对值得你尝试。它既满足了基础的文件存储需求，又融入了 AI 智能与向量搜索等前沿特性，是构建现代化私有云存储的优秀选择。&lt;/p&gt;
&lt;p&gt;快去试试吧！相信它也会成为你的心头好～&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;🌐 项目地址：&lt;a href=&quot;https://github.com/CooperJiang/PixelPunk&quot;&gt;https://github.com/CooperJiang/PixelPunk&lt;/a&gt;
📚 详细文档：&lt;a href=&quot;https://pixelpunk.cc/docs/getting-started&quot;&gt;项目文档&lt;/a&gt;
🌐 站长部署地址：&lt;a href=&quot;https://pixel.santisify.top&quot;&gt;https://pixel.santisify.top&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;本文由实际部署体验编写，内容基于 PixelPunk 最新版本。&lt;/em&gt;
&lt;em&gt;如有疑问或建议，欢迎在 GitHub 仓库提出 Issue 或参与讨论。&lt;/em&gt;&lt;/p&gt;</content:encoded><h:img src="/_astro/pixelpunk.Dst_bIt8.png"/><enclosure url="/_astro/pixelpunk.Dst_bIt8.png"/></item><item><title>十年火线，青春不散—致十年CFM岁月</title><link>https://santisify.top/blog/other/cf10</link><guid isPermaLink="true">https://santisify.top/blog/other/cf10</guid><pubDate>Fri, 07 Nov 2025 21:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;初遇火线，热血依旧&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;十年成长，见证变迁&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;友情与青春的见证&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;十周年，我们的荣耀时刻&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;致未来，火线情不散&lt;/h2&gt;
&lt;hr&gt;</content:encoded><h:img src="/_astro/cf10.Dq_J3ENE.jpg"/><enclosure url="/_astro/cf10.Dq_J3ENE.jpg"/></item><item><title>AtCoder Beginner Contest 430</title><link>https://santisify.top/blog/atcoder/abc430</link><guid isPermaLink="true">https://santisify.top/blog/atcoder/abc430</guid><description>abc430 (A---C)</description><pubDate>Sat, 01 Nov 2025 20:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A Candy Cookie Law&lt;/h2&gt;
&lt;p&gt;A Candy Cookie Law&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给四个数字$A$, $B$, $C$, $D$, 若 $C \ge A$的同时 $D \ge B$,输出 $No$.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int a, b, c, d;
    std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; c &gt;&gt; d;
    if ((c &gt;= a &amp;#x26;&amp;#x26; d &gt;= b) || c &amp;#x3C; a) {
        std::cout &amp;#x3C;&amp;#x3C; &quot;No&quot; &amp;#x3C;&amp;#x3C; std::endl;
    } else {
        std::cout &amp;#x3C;&amp;#x3C; &quot;Yes&quot; &amp;#x3C;&amp;#x3C; std::endl;
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    // std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B Count Subgrid&lt;/h2&gt;
&lt;p&gt;B Count Subgrid&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;$N \times N$ 的矩阵中包含多少种不同的 $M \times M$ 的子矩阵.&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;遍历矩阵，将每个子矩阵都转化为字符串存入 $map$，$map$ 大小即为答案.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n, m;
    std::cin &gt;&gt; n &gt;&gt; m;
    std::map&amp;#x3C;std::string, int&gt; mp;;
    std::vector&amp;#x3C;std::string&gt; a(n);
    for (int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i];
    }
    for (int i = 0; i &amp;#x3C; n - m + 1; i ++) {
        for (int j = 0; j &amp;#x3C; n - m + 1; j ++) {
            std::string s = &quot;&quot;;
            for (int l = 0; l &amp;#x3C; m; l ++) {
                for (int r = 0; r &amp;#x3C; m; r ++) {
                    s += a[i + l][j + r];
                }
            }
            mp[s] ++;
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; mp.size() &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    // std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C Truck Driver&lt;/h2&gt;
&lt;p&gt;C Truck Driver&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;一个字符串 $S$ 中存在多少个数对$[l, r]$，使得这个子串($S_{l}, S_{l+1} \cdots S_{r}$),满足字符 $a$ 个数 $ct_a \ge A$, 字符 $b$ 个数 $ct_b &amp;#x3C; B$&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;数据范围不允许使用暴力，那么只能使用二分，循环左边，二分右区间，二分条件就是$ct_a \ge A, ct_b &amp;#x3C; B$,但是我们不能直接一个二分查找，可以想到在一个区间内可能存在多个满足条件的值.
我们只有分别二分满足$ct_a=A, ct_b=B$的位置 $la, lb$，然后去取得两个的交集，其中，$lb$ 是有可能小于 $la$ 的.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n, a, b;
    std::cin &gt;&gt; n &gt;&gt; a &gt;&gt; b;
    std::string s;
    std::cin &gt;&gt; s;
    std::vector&amp;#x3C;int&gt; ct1(n + 1, 0), ct2(n + 1, 0);
    for (int i = 0; i &amp;#x3C; n; i ++) {
        ct1[i + 1] = ct1[i] + (s[i] == &apos;a&apos;);
        ct2[i + 1] = ct2[i] + (s[i] == &apos;b&apos;);
    }
    int ans = 0;
    for (int i = 0; i &amp;#x3C; n; i ++) {
        int l = i, r = n + 1, ll = i, rr = n + 1;
        while (std::abs(l - r) &gt; 1) {
            int mid = (l + r) &gt;&gt; 1;
            if (ct1[mid] - ct1[i] &gt;= a) r = mid;
            else l = mid;
        }
        while (std::abs(ll - rr) &gt; 1) {
            int mid = (ll + rr) &gt;&gt; 1;
            if (ct2[mid] - ct2[i] &amp;#x3C; b) ll = mid;
            else rr = mid;
        }
        ans += std::max(rr - r, 0ll);
    }

    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int T = 1;
    // std::cin &gt;&gt; T;
    while (T --) solve();
    return 0;
}

&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/3.BCB-OlsZ.webp"/><enclosure url="/_astro/3.BCB-OlsZ.webp"/></item><item><title>Vue学习笔记（三）</title><link>https://santisify.top/blog/other/vue3</link><guid isPermaLink="true">https://santisify.top/blog/other/vue3</guid><description>内置组件</description><pubDate>Fri, 24 Oct 2025 21:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Vue 内置组件学习笔记（核心组件实战整理）&lt;/h1&gt;
&lt;h2&gt;一、＜component＞：动态组件切换&lt;/h2&gt;
&lt;h3&gt;核心作用&lt;/h3&gt;
&lt;p&gt;通过 &lt;code&gt;is&lt;/code&gt; 属性动态渲染不同组件，实现无刷新切换页面 / 功能模块，提升组件复用性。&lt;/p&gt;
&lt;h3&gt;核心属性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;is&lt;/code&gt;：指定要渲染的组件（值为组件名字符串或组件对象）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;实战案例（Tab 标签页）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;button @click=&quot;currentComponent = &apos;Home&apos;&quot;&gt;首页&amp;#x3C;/button&gt;
    &amp;#x3C;button @click=&quot;currentComponent = &apos;List&apos;&quot;&gt;列表页&amp;#x3C;/button&gt;
    &amp;#x3C;!-- 动态渲染组件 --&gt;
    &amp;#x3C;component :is=&quot;currentComponent&quot;&gt;&amp;#x3C;/component&gt;
  &amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;script setup&gt;
import { ref } from &apos;vue&apos;

import Home from &apos;./Home.vue&apos;
import List from &apos;./List.vue&apos;

const currentComponent = ref(&apos;Home&apos;) // 初始渲染 Home 组件
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;常见误区&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;is&lt;/code&gt; 的值需与组件名完全匹配（区分大小写，建议使用 PascalCase 命名组件）。&lt;/li&gt;
&lt;li&gt;动态组件外若嵌套 &lt;code&gt;&amp;#x3C;keep-alive&gt;&lt;/code&gt;，需确保 &lt;code&gt;&amp;#x3C;component&gt;&lt;/code&gt; 是直接子元素，否则缓存失效。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二、＜keep-alive＞：组件缓存管理&lt;/h2&gt;
&lt;h3&gt;核心作用&lt;/h3&gt;
&lt;p&gt;缓存不活动的组件实例（而非销毁），保留组件状态（如表单输入、滚动位置），减少重复渲染。&lt;/p&gt;
&lt;h3&gt;核心属性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;include&lt;/code&gt;：仅缓存名称匹配的组件（值为字符串、正则或数组，匹配组件 &lt;code&gt;name&lt;/code&gt; 属性）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exclude&lt;/code&gt;：不缓存名称匹配的组件（规则同上）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max&lt;/code&gt;：最多缓存的组件实例数量（超出则销毁最早缓存的实例）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;实战案例（缓存 Tab 页数据）&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;div&gt;
    &amp;#x3C;button @click=&quot;currentComponent = &apos;UserForm&apos;&quot;&gt;用户表单&amp;#x3C;/button&gt;
    &amp;#x3C;button @click=&quot;currentComponent = &apos;LogList&apos;&quot;&gt;日志列表&amp;#x3C;/button&gt;
    &amp;#x3C;!-- 只缓存 UserForm 组件 --&gt;
    &amp;#x3C;keep-alive include=&quot;UserForm&quot;&gt;
      &amp;#x3C;component :is=&quot;currentComponent&quot;&gt;&amp;#x3C;/component&gt;
    &amp;#x3C;/keep-alive&gt;
  &amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;script setup&gt;
import { ref } from &apos;vue&apos;

import LogList from &apos;./LogList.vue&apos;
import UserForm from &apos;./UserForm.vue&apos; // 组件名需设置为 UserForm

const currentComponent = ref(&apos;UserForm&apos;)
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;注意事项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;缓存的组件不会触发 &lt;code&gt;created&lt;/code&gt;/&lt;code&gt;mounted&lt;/code&gt; 等生命周期，需用 &lt;code&gt;activated&lt;/code&gt;（激活时）、&lt;code&gt;deactivated&lt;/code&gt;（失活时）替代。&lt;/li&gt;
&lt;li&gt;若组件无 &lt;code&gt;name&lt;/code&gt; 属性，&lt;code&gt;include&lt;/code&gt;/&lt;code&gt;exclude&lt;/code&gt; 需匹配组件文件名（不推荐，建议显式定义 &lt;code&gt;name&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、＜slot＞：组件内容分发（插槽）&lt;/h2&gt;
&lt;h3&gt;核心作用&lt;/h3&gt;
&lt;p&gt;允许父组件向子组件传递自定义内容，实现组件的灵活扩展（如卡片头部、列表项操作按钮）。&lt;/p&gt;
&lt;h3&gt;三种用法及案例&lt;/h3&gt;
&lt;h4&gt;1. 默认插槽（无名称）&lt;/h4&gt;
&lt;p&gt;子组件接收父组件传递的默认内容：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;!-- 子组件 Card.vue --&gt;
&amp;#x3C;template&gt;
  &amp;#x3C;div class=&quot;card&quot;&gt;
    &amp;#x3C;slot&gt;&amp;#x3C;/slot&gt;
    &amp;#x3C;!-- 父组件内容会插入这里 --&gt;
  &amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;!-- 父组件使用 --&gt;
&amp;#x3C;Card&gt;
  &amp;#x3C;p&gt;这是卡片的默认内容&amp;#x3C;/p&gt; &amp;#x3C;!-- 会被插入到子组件的 &amp;#x3C;slot&gt; 中 --&gt;
&amp;#x3C;/Card&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 具名插槽（指定名称）&lt;/h4&gt;
&lt;p&gt;子组件定义多个命名插槽，父组件按需传递内容：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;!-- 子组件 Card.vue --&gt;
&amp;#x3C;template&gt;
  &amp;#x3C;div class=&quot;card&quot;&gt;
    &amp;#x3C;slot name=&quot;header&quot;&gt;&amp;#x3C;/slot&gt;
    &amp;#x3C;!-- 头部插槽 --&gt;
    &amp;#x3C;slot&gt;&amp;#x3C;/slot&gt;
    &amp;#x3C;!-- 默认插槽 --&gt;
    &amp;#x3C;slot name=&quot;footer&quot;&gt;&amp;#x3C;/slot&gt;
    &amp;#x3C;!-- 底部插槽 --&gt;
  &amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;!-- 父组件使用（Vue3 简写 # 替代 v-slot:） --&gt;
&amp;#x3C;Card&gt;
  &amp;#x3C;template #header&gt;
    &amp;#x3C;h3&gt;卡片标题&amp;#x3C;/h3&gt; &amp;#x3C;!-- 插入 header 插槽 --&gt;
  &amp;#x3C;/template&gt;
  &amp;#x3C;p&gt;卡片正文内容&amp;#x3C;/p&gt; &amp;#x3C;!-- 插入默认插槽 --&gt;
  &amp;#x3C;template #footer&gt;
    &amp;#x3C;button&gt;提交&amp;#x3C;/button&gt; &amp;#x3C;!-- 插入 footer 插槽 --&gt;
  &amp;#x3C;/template&gt;
&amp;#x3C;/Card&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;3. 作用域插槽（子传父数据）&lt;/h4&gt;
&lt;p&gt;子组件向父组件传递数据，父组件基于数据自定义渲染：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;!-- 子组件 List.vue --&gt;
&amp;#x3C;template&gt;
  &amp;#x3C;ul&gt;
    &amp;#x3C;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
      &amp;#x3C;!-- 向父组件传递 item 数据 --&gt;
      &amp;#x3C;slot :item=&quot;item&quot; :index=&quot;index&quot;&gt;&amp;#x3C;/slot&gt;
    &amp;#x3C;/li&gt;
  &amp;#x3C;/ul&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;script setup&gt;
const list = [
  { id: 1, name: &apos;张三&apos; },
  { id: 2, name: &apos;李四&apos; }
]
&amp;#x3C;/script&gt;

&amp;#x3C;!-- 父组件使用 --&gt;
&amp;#x3C;List&gt;
  &amp;#x3C;!-- 接收子组件传递的 item 数据，自定义渲染列表项 --&gt;
  &amp;#x3C;template #default=&quot;slotProps&quot;&gt;
    &amp;#x3C;span&gt;{{ slotProps.index + 1 }}. {{ slotProps.item.name }}&amp;#x3C;/span&gt;
    &amp;#x3C;button @click=&quot;edit(slotProps.item)&quot;&gt;编辑&amp;#x3C;/button&gt;
  &amp;#x3C;/template&gt;
&amp;#x3C;/List&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;关键技巧&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Vue3 中具名插槽可用 &lt;code&gt;#插槽名&lt;/code&gt; 简写（如 &lt;code&gt;#header&lt;/code&gt; 替代 &lt;code&gt;v-slot:header&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;作用域插槽的参数可解构简化（如 &lt;code&gt;#default=&quot;{ item, index }&quot;&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、＜transition＞ 与 ＜transition-group＞：过渡动画&lt;/h2&gt;
&lt;h3&gt;核心作用&lt;/h3&gt;
&lt;p&gt;为组件 / 元素的插入、更新、移除添加过渡动画，提升用户体验。&lt;/p&gt;
&lt;h4&gt;1. ＜transition＞：单个元素 / 组件过渡&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;button @click=&quot;show = !show&quot;&gt;切换&amp;#x3C;/button&gt;
  &amp;#x3C;!-- 为 p 标签添加过渡动画 --&gt;
  &amp;#x3C;transition name=&quot;fade&quot;&gt;
    &amp;#x3C;p v-if=&quot;show&quot;&gt;这是一段文本&amp;#x3C;/p&gt;
  &amp;#x3C;/transition&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;style&gt;
/* 进入/离开的过渡状态 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}
/* 进入开始/离开结束的状态 */
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
&amp;#x3C;/style&gt;

&amp;#x3C;script setup&gt;
import { ref } from &apos;vue&apos;

const show = ref(true)
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. ＜transition-group＞：列表过渡（多个元素）&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-vue&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;button @click=&quot;addItem&quot;&gt;添加项&amp;#x3C;/button&gt;
  &amp;#x3C;!-- 为列表项添加过渡 --&gt;
  &amp;#x3C;transition-group name=&quot;slide&quot; tag=&quot;ul&quot;&gt;
    &amp;#x3C;li v-for=&quot;item in list&quot; :key=&quot;item.id&quot;&gt;
      {{ item.name }}
    &amp;#x3C;/li&gt;
  &amp;#x3C;/transition-group&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;style&gt;
.slide-enter-active,
.slide-leave-active {
  transition: transform 0.3s ease;
}
.slide-enter-from {
  transform: translateX(30px);
  opacity: 0;
}
.slide-leave-to {
  transform: translateX(-30px);
  opacity: 0;
}
&amp;#x3C;/style&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;核心属性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;：定义过渡类名前缀（如 &lt;code&gt;name=&quot;fade&quot;&lt;/code&gt; 对应类名 &lt;code&gt;fade-enter-active&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tag&lt;/code&gt;（仅 transition-group）：指定渲染的容器标签（默认 &lt;code&gt;&amp;#x3C;span&gt;&lt;/code&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;五、综合实战要点&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;组件组合&lt;/strong&gt;：&lt;code&gt;＜component＞ + ＜keep-alive＞&lt;/code&gt; 实现带缓存的页面切换，&lt;code&gt;＜slot＞&lt;/code&gt; 实现组件个性化扩展（如后台管理系统的动态页面 + 自定义操作区）。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;问题解决&lt;/strong&gt;：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;缓存组件数据刷新：在 &lt;code&gt;activated&lt;/code&gt; 钩子中手动更新数据。&lt;/li&gt;
&lt;li&gt;插槽数据传递错误：检查作用域插槽的参数名是否与子组件一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;&lt;strong&gt;学习优先级&lt;/strong&gt;：先掌握 &lt;code&gt;＜component＞&lt;/code&gt; &lt;code&gt;＜keep-alive＞&lt;/code&gt; &lt;code&gt;＜slot＞&lt;/code&gt;（日常开发高频使用），再深入 &lt;code&gt;＜transition＞&lt;/code&gt; 动画细节。&lt;/li&gt;
&lt;/ol&gt;</content:encoded><h:img src="/_astro/vue3.DOez9DA0.png"/><enclosure url="/_astro/vue3.DOez9DA0.png"/></item><item><title>AtCoder Beginner Contest 425</title><link>https://santisify.top/blog/atcoder/abc425</link><guid isPermaLink="true">https://santisify.top/blog/atcoder/abc425</guid><description>abc425 (A---D)</description><pubDate>Tue, 14 Oct 2025 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A Sigma Cubes&lt;/h2&gt;
&lt;p&gt;A Sigma Cubes&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;输入$N$,计算$\sum_{i=1}^N (-1)^i \times i^3$&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	int res = 0;
	for(int i = 1; i &amp;#x3C;= n; i ++) {
		if(i &amp;#x26; 1) res -= i * i * i;
		else res += i * i * i;
	}

	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
  solve();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B Find Permutation 2&lt;/h2&gt;
&lt;p&gt;B Find Permutation 2&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给出数组 $A$, 判断是否存在一个排列 $P$ 使得满足:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$P$是一个排列。&lt;/li&gt;
&lt;li&gt;$P_{i}=A_{i}(A_{i} \neq -1)$, $P{i} = R (A_{i} = -1)$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;首先记录下 $A$ 中非 $-1$ 的其他数的个数记为 $ct$,若$ct_{i} \ge 2$ 则不可能有合法的 $P$
将 $ct_{i}$ 为 $0$ 的依次填入$A_{i}=-1$ 处即可获得排列 $P$.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; a(n + 1, 0), b(n + 1, 0);
	for(int i = 1; i &amp;#x3C;= n; i ++) {
		std::cin &gt;&gt; b[i];
		if(b[i] != -1) {
			a[b[i]] ++;
		}
	}

	for(int i = 1; i &amp;#x3C;= n; i ++) {
		if(a[i] &gt; 1) {
			std::cout &amp;#x3C;&amp;#x3C; &quot;No&quot; &amp;#x3C;&amp;#x3C; std::endl;
			return;
		}
	}
	std::cout &amp;#x3C;&amp;#x3C; &quot;Yes&quot; &amp;#x3C;&amp;#x3C; std::endl;
	std::queue&amp;#x3C;int&gt; q;
	for(int i = 1; i &amp;#x3C;= n; i ++) {
		if(!a[i]) {
			q.push(i);
		}
	}
	for(int i = 1; i &amp;#x3C;= n; i ++) {
		if(b[i] == -1) {
			std::cout &amp;#x3C;&amp;#x3C; q.front() &amp;#x3C;&amp;#x3C; &apos; &apos;;
			q.pop();
		}else {
			std::cout &amp;#x3C;&amp;#x3C; b[i] &amp;#x3C;&amp;#x3C; &apos; &apos;;
		}
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
  solve();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C Rotate and Sum Query&lt;/h2&gt;
&lt;p&gt;C Rotate and Sum Query&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给出数组 $A$ 和$q$次查询,每次查询如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1$   $c$: 循环 $c$ 次，每次循环都将 $A_{1}$ 放在数组末尾.&lt;/li&gt;
&lt;li&gt;$2$   $l$   $r$: 查询区间$[l, r]$的总和&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;数据范围：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1\le N\le 2\times 10^5$&lt;/li&gt;
&lt;li&gt;$1\le Q\le 2\times 10^5$&lt;/li&gt;
&lt;li&gt;$1\le A_i \le 10^9$&lt;/li&gt;
&lt;li&gt;$1\le c\le N$&lt;/li&gt;
&lt;li&gt;$1\le l\le r \le N$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;可以发现数据范围较大，无法使用rotate去模拟，但是可以发现每次循环次数 $ct$ 到达 $n$ 后就会回到初始数组，区间总和也只与$ct % n$有关.
我们可以使用变化后的区间 $[l, r]$ 和 $ct$ 去找变化前的区间 $[x, y]$,可以发现需要预处理前缀和 $s$. 
但是变化前的区间可能会出现 $x &gt; y$，这个区间$[y, x]$的值则是区间外的总和.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
	int n, q;
	std::cin &gt;&gt; n &gt;&gt; q;
	std::vector&amp;#x3C;int&gt; s(n + 1, 0), a(n + 1, 0);
	for (int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i];
		s[i] = a[i];
		if (i) s[i] = s[i - 1] + a[i];
	}
	int t, x, y, ct = 0;
	while (q--) {
		std::cin &gt;&gt; t &gt;&gt; x;
		if (t == 1) {
			ct += x;
		} else {
			std::cin &gt;&gt; y;
			x = (x - 1 + ct) % n;
			y = (y - 1 + ct) % n;
			if (x &gt; y) {
				std::cout &amp;#x3C;&amp;#x3C; s[y] + s[n - 1] - (x ? s[x - 1] : 0) &amp;#x3C;&amp;#x3C; std::endl;
			} else {
				std::cout &amp;#x3C;&amp;#x3C; s[y] - (x ? s[x - 1] : 0) &amp;#x3C;&amp;#x3C; std::endl;
			}
		}
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/2.S5ShRomU.webp"/><enclosure url="/_astro/2.S5ShRomU.webp"/></item><item><title>AtCoder Beginner Contest 424</title><link>https://santisify.top/blog/atcoder/abc424</link><guid isPermaLink="true">https://santisify.top/blog/atcoder/abc424</guid><description>abc424 (A---D)</description><pubDate>Sat, 20 Sep 2025 20:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A Isosceles&lt;/h2&gt;
&lt;p&gt;A Isosceles&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给出三角形的三个边$a$, $b$, $c$，判断三角形是否为等腰三角形。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int a, b, c;
    std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;
    if (a == b || a == c || b == c) {
        std::cout &amp;#x3C;&amp;#x3C; &quot;Yes&quot; &amp;#x3C;&amp;#x3C; std::endl;
    } else {
        std::cout &amp;#x3C;&amp;#x3C; &quot;No&quot; &amp;#x3C;&amp;#x3C; std::endl;
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    // std::cin &gt;&gt; _;
    while (_ --) solve();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B Perfect&lt;/h2&gt;
&lt;p&gt;B Perfect&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;$n$个人，$m$个题，总共$k$次提交，每次提交都是第$A_{i}$人完成第$B_{i}$题。
输出完成所有题的人的编号，有多个按最后一个题的完成顺序输出。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;直接统计完成题的数目，当数目达到$m$时，直接输出编号。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n, m, k;
    std::cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n + 1, 0);
    while (k --) {
        int x, y;
        std::cin &gt;&gt; x &gt;&gt; y;
        a[x] ++;
        if (a[x] == m) {
            std::cout &amp;#x3C;&amp;#x3C; x &amp;#x3C;&amp;#x3C; &apos; &apos;;
        }
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    // std::cin &gt;&gt; _;
    while (_ --) solve();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C New Skill Acquired&lt;/h2&gt;
&lt;p&gt;C New Skill Acquired&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;$n$个数对，数对${A_{i}, B_{i}}$表示到达点$A_{i}$或者$B_{i}$才可到达点$i$（即$A_{i} \rightarrow i，B_{i} \rightarrow i$）,$A_{i} = 0$ $B_{i} = 0$表示$i$点可直接到达.
问：最多能到达多少个点。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;题目描述很明了，直接建图，再$dfs$或$bfs$搜索即可.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;p&gt;bfs&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::queue&amp;#x3C;int&gt; q;
    std::vector&amp;#x3C;bool&gt; vis(n + 1, false);
    std::vector g(n + 1, std::vector&amp;#x3C;int&gt;());
    for (int i = 0, x, y; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; x &gt;&gt; y;
        if (!x) {
            q.push(i + 1);
            vis[i + 1] = true;
        }
        g[x].push_back(i + 1), g[y].push_back(i + 1);
    }
    while (!q.empty()) {
        auto u = q.front();
        q.pop();
        for (auto v: g[u]) {
            if (!vis[v]) vis[v] = true, q.push(v);
        }
    }
    int ans = 0;
    for (int i = 1; i &amp;#x3C;= n; i ++) {
        ans += vis[i];
    }

    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    // std::cin &gt;&gt; _;
    while (_ --) solve();
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D 2x2 Erasing 2&lt;/h2&gt;
&lt;p&gt;D 2x2 Erasing 2&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定$n * m$的矩阵，要求修改矩阵，使得不出现$2 * 2$的 &apos;#&apos; 的矩阵。
输出最小操作数。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;可以发现数据最大为 $100$ 组 $7 * 7$ 的矩阵，可以直接暴力$dfs$.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
	int n, m;
	std::cin &gt;&gt; n &gt;&gt; m;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; s[i];
	int ans = 1e9;
	std::function&amp;#x3C;void(int, int, int)&gt; dfs = ([&amp;#x26;](int x, int y, int res) {
		if (res &gt;= ans) return; //实测不添加等号会TLE
		if (y == m) {
			y = 0, x++;
		}
		if (x == n) {
			ans = res;
			return;
		}

		if (s[x][y] == &apos;.&apos;) {
			dfs(x, y + 1, res);
			return;
		} else {
			if (x == 0 || y == 0 || s[x - 1][y] == &apos;.&apos; || s[x][y - 1] == &apos;.&apos; || s[x - 1][y - 1] == &apos;.&apos;)
				dfs(x, y + 1, res);
			s[x][y] = &apos;.&apos;;
			dfs(x, y + 1, res + 1);
			s[x][y] = &apos;#&apos;;
		}
	});
	dfs(0, 0, 0);
	std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int _ = 1;
	std::cin &gt;&gt; _;
	while (_--) solve();
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/1.9JjlDy8B.webp"/><enclosure url="/_astro/1.9JjlDy8B.webp"/></item><item><title>Educational Codeforces Round 182 (div2)</title><link>https://santisify.top/blog/codeforces/cf2144</link><guid isPermaLink="true">https://santisify.top/blog/codeforces/cf2144</guid><description>cf2144 (A---D)</description><pubDate>Tue, 16 Sep 2025 14:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A Cut the Array&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2144/problem/A&quot;&gt;Cut the Array&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定数组 $A$, 需要输出满足以下的 $l$ , $r$ ：&lt;/p&gt;
&lt;p&gt;$$s_{1} = \sum^{l}&lt;em&gt;{i=1}A&lt;/em&gt;{i} \ Mod\  3$$&lt;/p&gt;
&lt;p&gt;$$s_{2} = \sum^{r}&lt;em&gt;{i=l + 1}A&lt;/em&gt;{i} \ Mod\  3$$&lt;/p&gt;
&lt;p&gt;$$s_{3} = \sum^{n}&lt;em&gt;{i=r + 1}A&lt;/em&gt;{i} \ Mod\  3$$&lt;/p&gt;
&lt;p&gt;$s_{1}$, $s_{2}$, $s_{3}$ 互不相同或者都相同。若不存在输出 $0 \ 0$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于 $n$ 的数据范围较小，我们可以直接枚举每个 $l$ , $r$， 满足条件直接输出即可.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n + 1), s(n + 1, 0);
    for (int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i + 1];
        s[i + 1] = s[i] + a[i + 1];
    }

    for (int l = 1; l &amp;#x3C; n; l ++) {
        for (int r = l + 1; r &amp;#x3C; n; r ++) {
            int s1 = s[l], s2 = s[r] - s[l], s3 = s[n] - s[r];
            if (s1 % 3 == s2 % 3 &amp;#x26;&amp;#x26; s2 % 3 == s3 % 3) {
                std::cout &amp;#x3C;&amp;#x3C; l &amp;#x3C;&amp;#x3C; &apos; &apos; &amp;#x3C;&amp;#x3C; r &amp;#x3C;&amp;#x3C; std::endl;
                return;
            }
            if (s1 % 3 != s2 % 3 &amp;#x26;&amp;#x26; s1 % 3 != s3 % 3 &amp;#x26;&amp;#x26; s2 % 3 != s3 % 3) {
                std::cout &amp;#x3C;&amp;#x3C; l &amp;#x3C;&amp;#x3C; &apos; &apos; &amp;#x3C;&amp;#x3C; r &amp;#x3C;&amp;#x3C; std::endl;
                return;
            }
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; &quot;0 0&quot; &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin . tie(nullptr), std::cout . tie(nullptr);
    int ___ = 1;
    std::cin &gt;&gt; ___;
    while (___ --) solve();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B Maximum Cost Permutation&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2144/problem/B&quot;&gt;Maximum Cost Permutation&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个长度为 $n$ 的数组, 数组中的数都为非负整数，并且正整数不重复，现在将数组中的 $0$ 替换为正整数，并且与已有的不重复。&lt;/p&gt;
&lt;p&gt;现定义代价为：将这个数组变为递增的数组，所操作的区间大小。&lt;/p&gt;
&lt;p&gt;输出最大的代价&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以发现要想要代价最大就需要将数组尽可能的变为递减的数组，那么就可以将尽可能大的数放在前面，这样就可以使得代价最大&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n), ct(n + 1, 0), q;
    for (int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i];
        ct[a[i]] ++;
    }

    for (int i = 1; i &amp;#x3C;= n; i ++) {
        if (ct[i] == 0) q.push_back(i);
    }
    std::reverse(q.begin(), q.end());
    int opt = 0;
    for (int i = 0; i &amp;#x3C; n; i ++) {
        if (a[i] == 0) {
            a[i] = q[opt ++];
        }
    }
    int l = 0, r = n - 1;
    while (a[l] == l + 1 &amp;#x26;&amp;#x26; l + 1 &amp;#x3C; n) l ++;
    while (a[r] == r + 1 &amp;#x26;&amp;#x26; r &gt;= 0) r --;

    if (l &gt; r) {
        std::cout &amp;#x3C;&amp;#x3C; 0 &amp;#x3C;&amp;#x3C; std::endl;
    } else {
        std::cout &amp;#x3C;&amp;#x3C; r - l + 1 &amp;#x3C;&amp;#x3C; std::endl;
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int ___ = 1;
    std::cin &gt;&gt; ___;
    while (___ --) solve();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C Non-Descending Arrays&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2144/problem/C&quot;&gt;Non-Descending Arrays&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;两个数组 $a$, $b$。你可以选择&lt;strong&gt;一些&lt;/strong&gt;下标 $i$，使得这些下标对应的位置交换。最后要使得两个数组都是升序。求方案数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;显然只有交换和不交换两个状态。那么记 $dp[i][0/1]$ 表示第个位置交换/不交换使得前缀升序的方案数，那么考虑 $i - 1$ 交不交换，看两个位置是否合法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;p&gt;代码省略取模类可参考&lt;a href=&quot;https://santisify.top/blog/old/jiangly-template/#05a---%E5%8F%96%E6%A8%A1%E7%B1%BBmlong--mint&quot;&gt;jly算法模板&lt;/a&gt;，当然也可以选择边加边模&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;
// 此处放置取模类

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n + 1), b(n + 1);
    std::vector dp(n + 1, std::array&amp;#x3C;Z, 2&gt;{});

    for (int i = 0; i &amp;#x3C; n; i ++) std::cin &gt;&gt; a[i + 1];
    for (int i = 0; i &amp;#x3C; n; i ++) std::cin &gt;&gt; b[i + 1];
    dp[1][0] = 1;
    dp[1][1] = 1;
    for (int i = 1; i &amp;#x3C;= n; i ++) {
        if (a[i] &gt;= a[i - 1] &amp;#x26;&amp;#x26; b[i] &gt;= b[i - 1]) {
            dp[i][0] += dp[i - 1][0];
            dp[i][1] += dp[i - 1][1];
        }
        if (a[i] &gt;= b[i - 1] &amp;#x26;&amp;#x26; b[i] &gt;= a[i - 1]) {
            dp[i][0] += dp[i - 1][1];
            dp[i][1] += dp[i - 1][0];
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; dp[n][1] + dp[n][0] &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    std::cin &gt;&gt; _;
    while (_ --) solve();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D Price Tags&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2144/problem/D&quot;&gt;Price Tags&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;一个数组 $a$，和一个正整数 $y$ ，将数组的每个数都变为 $\lceil\frac{a_{i}}{x}\rceil$。&lt;/p&gt;
&lt;p&gt;代价为: 将变化后与变化前出现相同的数逐个删除，剩余的数的个数 $w$, 变化后的数组 $a$ 的总和$s$，计算 $w \times y + s$ 的最大值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于数组元素都是向上取整，可以发现，在一个区间 $[(x-1)*m+1, x * m]$ 在做运算后都是 $m$，那么我们就可以对 $a$ 数组进行区间处理。&lt;/p&gt;
&lt;p&gt;记 $ma$ 为 $a$ 中最大值，那么对于一个 $x$，所有数操作后的值域都在 $[1, \frac{ma}{x}]$ 之间，那么考虑枚举 $x$，对于一个值 $j$，除 $x$ 向上取整后会变成的数的范围为 $[(j - 1)&lt;em&gt;x+1, j&lt;/em&gt;x]$，用前缀和记录这个范围原本有多少数，就可以得到和原本 $j$ 的个数的差异。最后计算出答案即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define pii std::pair&amp;#x3C;int,int&gt;

void solve() {
    int n, c, ma = -1e8;
    std::cin &gt;&gt; n &gt;&gt; c;
    std::vector&amp;#x3C;int&gt; a(n), ct(200005, 0);
    for (int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i];
        ct[a[i]] ++;
        ma = std::max(ma, a[i]);
    }

    if (ma == 1) {
        std::cout &amp;#x3C;&amp;#x3C; n &amp;#x3C;&amp;#x3C; std::endl;
        return;
    }

    auto s = ct;
    for (int i = 1; i &amp;#x3C; 200005; i ++) {
        s[i] += s[i - 1];
    }

    int ans = -1e18;
    for (int x = 2; x &amp;#x3C;= ma; x ++) {
        int m = (ma + x - 1) / x;
        int res = 0;
        for (int j = 1; j &amp;#x3C;= m; j ++) {
            int l = (j - 1) * x + 1, r = std::min(ma, j * x);
            if (l &gt; ma) {
                break;
            }
            int w = s[r] - s[l - 1];
            res += w * j;
            res -= c * std::max(0ll, w - ct[j]);
        }
        ans = std::max(res, ans);
    }

    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int _ = 1;
    std::cin &gt;&gt; _;
    while (_ --) solve();
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/2.CdMgzZJa.webp"/><enclosure url="/_astro/2.CdMgzZJa.webp"/></item><item><title>Codeforces Round 1042 (Div. 3)</title><link>https://santisify.top/blog/codeforces/cf2131</link><guid isPermaLink="true">https://santisify.top/blog/codeforces/cf2131</guid><description>cf2131 (A---)</description><pubDate>Fri, 29 Aug 2025 20:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/2131/problem/A&quot;&gt;Lever&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定两个长度为 $n$ 的数组 $A$,$B$ .现在有以下两个操作：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;选择一个下标 $i$ ,若$A_{i}&gt;B_{i}$，则$A_{i}=A_{i}-1$. 如果不存在这样的$i$，则忽略此步骤.&lt;/li&gt;
&lt;li&gt;选择一个下标 $i$ ,若$A_{i}&amp;#x3C;B_{i}$，则$A_{i}=A_{i}+1$. 如果不存在这样的$i$，则忽略此步骤.
当执行完第二步都会检查第一步是否执行，若未执行则直接结束。
问：迭代的次数是多少？&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;可以发现两个操作都是操作 $A$ 数组，$B$ 数组没有变化过。既然这样，我们就可以只考虑 $A_{i}$和$B_{i}$ 的大小关系. 不懂的，可以看样例1.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n;
    std::cin &gt;&gt; n;
    int ans = 1;
    std::vector&amp;#x3C;int&gt; a(n);
    for (int i = 0; i &amp;#x3C; n; i++) {
       std::cin &gt;&gt; a[i];
    }
    for (int i = 0, x; i &amp;#x3C; n; i++) {
       std::cin &gt;&gt; x;
       if (a[i] &gt; x) ans += a[i] - x;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/2131/problem/B&quot;&gt;Alternating Series&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;构造一个数组 $A$,使得数组 $A(|A_{1}|,|A_{2}|,\cdots,|A_{n}|)$的字典序最下,并且长度大于等于$2$的子数组的和为正数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;可以发现奇数位可以先填$-1$,这样可以保证字典序最小,依次考虑偶数位,由于前后都是$-1$,且要保证和大于等于$2$,那么偶数位只能填$3$.虽然这样填可以满足和为正数,但是会有个新的问题,不能保证字典序最小.&lt;/p&gt;
&lt;p&gt;例如$6$的构造：${-1,3,-1,3,-1，3}$，当取第$5$，$6$位的长度为$2$的子数组${-1,3}$就会发现，最后一位可以为$2$，依次可以推理出：当长度为偶数，那么最后一位应该为$2$。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n;
    std::cin &gt;&gt; n;
    for (int i = 0; i &amp;#x3C; n; i++) {
       if (i % 2 == 0) {
          std::cout &amp;#x3C;&amp;#x3C; -1 &amp;#x3C;&amp;#x3C; &apos; &apos;;
       } else if (i == n - 1) {
          std::cout &amp;#x3C;&amp;#x3C; 2 &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
       } else {
          std::cout &amp;#x3C;&amp;#x3C; 3 &amp;#x3C;&amp;#x3C; &apos; &apos;;
       }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/2131/problem/C&quot;&gt;Make it Equal&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给出两个数组$S$, $T$，我们可以对$S$进行任意次以下操作：
将$S_{i}$修改为$S_{i}+k$或者$|S_{i}-k|$.
是否可以将$S$变为$T$?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于变化的大小都是$k$，则可以看作$S_{i} + t * k = T_{j} (t \in Z)$
那么我们可以将$S$和$T$都对$k$取余,但是可能出现$S_{i} = k - T_{i}$,我们可以将小于等于$\frac{k}{2}$的数做一个变形,变为$k-S_{i}$或者$k-T_{i}$,最后再排序,检查是否相同.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n), b(n);
    for (int i = 0; i &amp;#x3C; n; i++) {
       std::cin &gt;&gt; a[i];
       a[i] %= k;
       if (a[i] &amp;#x3C;= k / 2) {
          a[i] = k - a[i];
       }
    }
    for (int i = 0; i &amp;#x3C; n; i++) {
       std::cin &gt;&gt; b[i];
       b[i] %= k;
       if (b[i] &amp;#x3C;= k / 2) {
          b[i] = k - b[i];
       }
    }
    std::sort(a.begin(), a.end());
    std::sort(b.begin(), b.end());
    std::cout &amp;#x3C;&amp;#x3C; (a == b ? &quot;YES&quot; : &quot;NO&quot;) &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D &lt;a href=&quot;https://codeforces.com/contest/2131/problem/D&quot;&gt;Arboris Contractio&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;选择一条简单路径$s\to t$，然后将路径上除了$s$以外的所有点都直接连接到$s$上（即变成s的直连儿子）。即每次操作实际上是将一条路径“收缩”到起点$s$，使得路径上的所有点都直接连到$s$。这样，操作后从s到路径上任意一点的距离都变为$1$（除了$s$自己），而原来路径上的分支结构被改变。
最小化直径，并求达到最小直径所需的最少操作次数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;最终树是双星结构（有两个中心相邻）。
我们需要选择一条边（u,v）作为中心边，使得u和v覆盖的叶子数最多（即u的叶子邻居数+v的叶子邻居数，注意如果u是叶子则包括自己，v同理）。
那么，最少操作次数就是总叶子数减去最大覆盖叶子数（即leaf - ans）。
因为已经覆盖的叶子不需要操作（它们已经直接连接到中心），而未覆盖的叶子每个都需要一次操作来提升（将它直接连接到某个中心）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector g(n + 1, std::vector&amp;#x3C;int&gt;());
    for (int i = 0, u, v; i &amp;#x3C; n - 1; i++) {
       std::cin &gt;&gt; u &gt;&gt; v;
       g[u].push_back(v);
       g[v].push_back(u);
    }
    int leaf = 0, ans = 0;
    for (int i = 1; i &amp;#x3C;= n; i++) {
       if (g[i].size() == 1) leaf++;
       int res = (g[i].size() == 1);
       for (auto v : g[i]) {
          res += (g[v].size() == 1);
       }
       ans = std::max(res, ans);
    }
    std::cout &amp;#x3C;&amp;#x3C; leaf - ans &amp;#x3C;&amp;#x3C; std::endl;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/1.C1O7-_WW.webp"/><enclosure url="/_astro/1.C1O7-_WW.webp"/></item><item><title>2025省赛预选赛补题</title><link>https://santisify.top/blog/old/2025sichuan-icpc-pre</link><guid isPermaLink="true">https://santisify.top/blog/old/2025sichuan-icpc-pre</guid><description>由成信大出题</description><pubDate>Sun, 27 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;(cf补题链接)[https://codeforces.com/gym/606649]&lt;/p&gt;
&lt;h2&gt;H&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定三个数组$A$, $B$, $C$,长度分别为 $n$, $m$, $p$,每个数组取一个数求和，输出前$k$个最大值。&lt;/p&gt;
&lt;p&gt;数据范围： $l \le n,m,p \le 1000$, $1 \le k \le min(3000, n \times m \times p)$ , $0 \le A_{i}, B_{i}, C_{i} \le  10000000000$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;首先想到的最简单的思路是暴力求解，这样的时间复杂度将会是$1e^{9} \log_{2} ^{1e^{9}}$ ，如何优化呢？&lt;br&gt;
我们可以将其中两个数组合并，这里我们选择将$A, B$ 两个数组合并，然后进行排序，这里复杂度为$1e^{6}\log_{2}^{1e^{6}}$,
我么选择合并后的前$k$个最大值和数组$C$合并，这里的复杂度为$3e^{3} \times 1e^{3}$, 可以用堆维护$k$个数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

using i128 = __int128;
#define endl &apos;\n&apos;
#define int long long
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
  int n, m, p, k;
  std::cin &gt;&gt; n &gt;&gt; m &gt;&gt; p &gt;&gt; k;
  std::vector&amp;#x3C;int&gt; a(n), b(m), c(p);
  for(int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
  for(int i = 0; i &amp;#x3C; m; i++) std::cin &gt;&gt; b[i];
  for(int i = 0; i &amp;#x3C; p; i++) std::cin &gt;&gt; c[i];
  std::vector&amp;#x3C;int&gt; ab;
  for(int i = 0; i &amp;#x3C; n; i++) {
   for(int j = 0; j &amp;#x3C; m; j++) {
    ab.push_back(a[i] + b[j]);
   }
  }
  std::sort(ab.begin(), ab.end(), std::greater&amp;#x3C;&gt;());
  std::sort(c.begin(), c.end(), std::greater&amp;#x3C;&gt;());
  std::priority_queue&amp;#x3C;int, std::vector&amp;#x3C;int&gt;, std::greater&amp;#x3C;&gt; &gt; pq;
  for(int i = 0; i &amp;#x3C; std::min(k, (int) ab.size()); i++) {
   for(int j = 0; j &amp;#x3C; p; j++) {
    int t = ab[i] + c[j];
    if (pq.size() == k) {
     auto w = pq.top();
     if (w &amp;#x3C; t) {
      pq.pop();
      pq.push(t);
     }
    } else {
     pq.push(t);
    }
   }
  }
  std::vector&amp;#x3C;int&gt; res;
  while (!pq.empty()) {
   res.push_back(pq.top());
   pq.pop();
  }
  std::reverse(res.begin(), res.end());
  for(auto i : res) {
   std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; endl;
  }
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  solve();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;E&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个长度为$n$的数组$A$, 有$q$次询问,每次给出$l, r, start, end$, 对于每次询问，我们要输出$A$中在区间段$[l,r]$
中,$start \le A_{i} \le end$的数的个数。&lt;/p&gt;
&lt;p&gt;数据范围：$1 \le N, q \le 10^{5}, -10^{12} \le A_{i} \le 10^{12}$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;赛时，我想的是对区间内的数排序,然后二分查找边界,计算数量,奈何&lt;code&gt;TLE&lt;/code&gt;,tql,显然是排序超时了。&lt;br&gt;
正解是树状数组或者线段树&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

using i128 = __int128;
#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;
std::mt19937_64 rng(std::chrono::system_clock::now().time_since_epoch().count());
std::vector&amp;#x3C;int&gt; a(MAX_N);
struct Node {
  int l{}, r{};
  std::vector&amp;#x3C;int&gt; sorted;
};

Node tr[4 * MAX_N];

void build(int u, int l, int r) {
  tr[u].l = l;
  tr[u].r = r;
  tr[u].sorted.clear();
  if (l == r) {
   tr[u].sorted.push_back(a[l]);
   return;
  }
  int mid = (l + r) / 2;
  build(u &amp;#x3C;&amp;#x3C; 1, l, mid);
  build(u &amp;#x3C;&amp;#x3C; 1 | 1, mid + 1, r);
  auto &amp;#x26;left = tr[u &amp;#x3C;&amp;#x3C; 1].sorted;
  auto &amp;#x26;right = tr[u &amp;#x3C;&amp;#x3C; 1 | 1].sorted;
  tr[u].sorted.resize(left.size() + right.size());
  merge(left.begin(), left.end(), right.begin(), right.end(), tr[u].sorted.begin());
}

int query(int u, int l, int r, int start, int end) {
  if (tr[u].r &amp;#x3C; l || tr[u].l &gt; r) {
   return 0;
  }
  if (l &amp;#x3C;= tr[u].l &amp;#x26;&amp;#x26; tr[u].r &amp;#x3C;= r) {
   auto &amp;#x26;v = tr[u].sorted;
   int left_pos = lower_bound(v.begin(), v.end(), start) - v.begin();
   int right_pos = upper_bound(v.begin(), v.end(), end) - v.begin();
   return right_pos - left_pos;
  }
  return query(u &amp;#x3C;&amp;#x3C; 1, l, r, start, end) + query(u &amp;#x3C;&amp;#x3C; 1 | 1, l, r, start, end);
}

void solve() {
  int N, Q;
  std::cin &gt;&gt; N &gt;&gt; Q;
  for(int i = 1; i &amp;#x3C;= N; ++i) {
   std::cin &gt;&gt; a[i];
  }
  build(1, 1, N);
  while (Q--) {
   int l, r, s, e;
   std::cin &gt;&gt; l &gt;&gt; r &gt;&gt; s &gt;&gt; e;
   std::cout &amp;#x3C;&amp;#x3C; query(1, l, r, s, e) &amp;#x3C;&amp;#x3C; endl;
  }
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  solve();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/8.Q_Bi3OUW.webp"/><enclosure url="/_astro/8.Q_Bi3OUW.webp"/></item><item><title>Restful API Tips</title><link>https://santisify.top/blog/old/restfulapi</link><guid isPermaLink="true">https://santisify.top/blog/old/restfulapi</guid><description>API设计小Tips</description><pubDate>Fri, 21 Mar 2025 16:36:32 GMT</pubDate><content:encoded>&lt;h2&gt;API请求&lt;/h2&gt;
&lt;h3&gt;HTTP动词&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;GET:     读取（READ）
POST:    新建（CREATE）
PUT:     更新（UPDATE）
DELETE:  删除（DELETE）
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;PATCH 部分更新&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;URL宾语&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;宾语&lt;/strong&gt; 顾名思义，是一个名词，&lt;code&gt;URL&lt;/code&gt;作为&lt;code&gt;API&lt;/code&gt;的宾语是作用&lt;code&gt;HTTP&lt;/code&gt;的对象，普遍以复数形式存在.&lt;/p&gt;
&lt;p&gt;以下为错误示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/getAllCars
/createNewCar
/deleteAllRedCars
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正确示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/aticles
/users
/cars
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;煮个栗子&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt; GET    /zoos：列出所有动物园
 POST   /zoos：新建一个动物园
 GET    /zoos/ID：获取某个指定动物园的信息
 PUT    /zoos/ID：更新某个指定动物园的信息（提供该动物园的全部信息）
 PATCH  /zoos/ID：更新某个指定动物园的信息（提供该动物园的部分信息）
 DELETE /zoos/ID：删除某个动物园
 GET    /zoos/ID/animals：列出某个指定动物园的所有动物
 DELETE /zoos/ID/animals/ID：删除某个指定动物园的指定动物
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;过滤（filter）&lt;/h3&gt;
&lt;p&gt;通常在数据库中存储着许多数据，我们不可能将所有数据返回给用户，而是选择性的将一些数据返回给用户，而&lt;code&gt;API&lt;/code&gt;就应该提供一些参数，过滤返回的结果。&lt;/p&gt;
&lt;p&gt;下面是一些常见的参数。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;?limit=10：指定返回记录的数量
?offset=10：指定返回记录的开始位置。
?page=2&amp;#x26;per_page=100：指定第几页，以及每页的记录数。
?sortby=name&amp;#x26;order=asc：指定返回结果按照哪个属性排序，以及排序顺序。
?animal_type_id=1：指定筛选条件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;参数的设计允许存在冗余，即允许API路径和URL参数偶尔有重复。比如，&lt;code&gt;GET /zoo/ID/animals&lt;/code&gt; 与 &lt;code&gt;GET /animals?zoo_id=ID&lt;/code&gt; 的含义是相同的。&lt;/p&gt;
&lt;h3&gt;不符合 CRUD 情况的 RESTful API&lt;/h3&gt;
&lt;p&gt;在实际资源操作中，总会有一些不符合 CRUD 的情况，一般有几种处理方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1、使用 POST，为需要的动作增加一个 endpoint，使用 POST 来执行动作，比如: POST /resend 重新发送邮件。&lt;/li&gt;
&lt;li&gt;2、增加控制参数，添加动作相关的参数，通过修改参数来控制动作。比如一个博客网站，会有把写好的文章“发布”的功能，可以用上面的 &lt;code&gt;POST /articles/{:id}/publish&lt;/code&gt; 方法，也可以在文章中增加 &lt;code&gt;published:boolean&lt;/code&gt; 字段，发布的时候就是更新该字段 &lt;code&gt;PUT /articles/{:id}?published=true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;3、把动作转换成资源，把动作转换成可以执行 CRUD 操作的资源， github 就是用了这种方法。
比如“喜欢”一个 gist，就增加一个 &lt;code&gt;/gists/:id/star&lt;/code&gt; 子资源，然后对其进行操作：“喜欢”使用&lt;code&gt;PUT /gists/:id/star&lt;/code&gt;，“取消喜欢”使用 &lt;code&gt;DELETE /gists/:id/star&lt;/code&gt;。
另外一个例子是 Fork，这也是一个动作，但是在 gist 下面增加 forks资源，就能把动作变成 CRUD 兼容的：&lt;code&gt;POST /gists/:id/forks&lt;/code&gt; 可以执行用户 fork 的动作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;动词覆盖，应对服务器不完全支持 HTTP 的情况&lt;/h3&gt;
&lt;p&gt;有些客户端只能使用GET和POST这两种方法。服务器必须接受POST模拟其他三个方法（PUT、PATCH、DELETE）。
这时，客户端发出的 HTTP 请求，要加上X-HTTP-Method-Override属性，告诉服务器应该使用哪一个动词，覆盖POST方法。&lt;/p&gt;
&lt;h2&gt;API响应&lt;/h2&gt;
&lt;h3&gt;状态码&lt;/h3&gt;
&lt;h4&gt;2xx 状态码&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;200&lt;/code&gt;状态码也称成功状态码，但是对于不同的方法又有不同的状态码&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GET --&gt; &lt;code&gt;200&lt;/code&gt; OK&lt;/li&gt;
&lt;li&gt;POST--&gt; &lt;code&gt;201&lt;/code&gt; Created（表示生成新的资源）&lt;/li&gt;
&lt;li&gt;PUT --&gt; &lt;code&gt;200&lt;/code&gt; OK&lt;/li&gt;
&lt;li&gt;PATCH --&gt; &lt;code&gt;200&lt;/code&gt; OK&lt;/li&gt;
&lt;li&gt;DELETE --&gt; &lt;code&gt;204&lt;/code&gt; No Content（表示该资源已不存在）&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;3xx 状态码&lt;/h4&gt;
&lt;p&gt;在&lt;strong&gt;Restful API&lt;/strong&gt;中用不上，永久重定向（&lt;code&gt;301&lt;/code&gt;）、暂时重定向（&lt;code&gt;302&lt;/code&gt;、&lt;code&gt;307&lt;/code&gt;）可由应用级别返回，浏览器直接跳转。
主要使用&lt;code&gt;303&lt;/code&gt; see other，以表示参考另一个URL，它与302和307的含义一样，也是”暂时重定向”，区别在于302和307用于GET请求，而303用于POST、PUT和DELETE请求。收到303以后，浏览器不会自动跳转，而会让用户自己决定下一步怎么办。&lt;/p&gt;
&lt;h4&gt;4xx 状态码&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;4xx&lt;/code&gt; 状态码表示客户端错误，主要有下面几种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;400&lt;/code&gt; --&gt; Bad Request：服务器不理解客户端的请求，未做任何处理。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;401&lt;/code&gt; --&gt; Unauthorized：用户未提供身份验证凭据，或者没有通过身份验证。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;403&lt;/code&gt; --&gt; Forbidden：用户通过了身份验证，但是不具有访问资源所需的权限。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404&lt;/code&gt; --&gt; Not Found：所请求的资源不存在，或不可用。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;405&lt;/code&gt; --&gt; Method Not Allowed：用户已经通过身份验证，但是所用的 HTTP 方法不在他的权限之内。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;410&lt;/code&gt; --&gt; Gone：所请求的资源已从这个地址转移，不再可用。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;415&lt;/code&gt; --&gt; Unsupported Media Type：客户端要求的返回格式不支持。比如，客户端要求返回XML格式，API只能返回JSON格式。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;422&lt;/code&gt; --&gt; Unprocessable Entity ：客户端上传的附件无法处理，导致请求失败。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;429&lt;/code&gt; --&gt; Too Many Requests：客户端的请求次数超过限额。&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;5xx 状态码&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;5xx&lt;/code&gt;状态码表示服务端错误。一般来说，&lt;strong&gt;API&lt;/strong&gt;不会向用户透露服务器的详细信息，所以只要两个状态码就够了。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;500&lt;/code&gt; --&gt; Internal Server Error：客户端请求有效，服务器处理时发生了意外。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;503&lt;/code&gt; --&gt; Service Unavailable：服务器无法处理请求，一般用于网站维护状态。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;返回数据&lt;/h3&gt;
&lt;p&gt;以下事项均为注意事项，不要问为什么，因为站长在学之前全都犯过。&lt;/p&gt;
&lt;h4&gt;不要返回纯本文&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;API&lt;/code&gt; 返回的数据格式，不应该是纯文本，而应该是一个 JSON 对象，因为这样才能返回标准的结构化数据。所以，服务器回应的 HTTP 头的&lt;strong&gt;Content-Type&lt;/strong&gt;属性要设为&lt;code&gt;application/json&lt;/code&gt;。
客户端请求时，也要明确告诉服务器，可以接受 JSON 格式，即请求的 HTTP 头的ACCEPT属性也要设成&lt;code&gt;application/json&lt;/code&gt;。&lt;/p&gt;
&lt;h4&gt;不要包装数据&lt;/h4&gt;
&lt;p&gt;response 的 body直接就是数据，不要做多余的包装。错误实例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;success&quot;: true,
  &quot;data&quot;: {
    &quot;id&quot;: 1,
    &quot;name&quot;: &quot;周伯通&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;针对不同操作，服务器向用户返回的结果应该符合以下规范。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; GET    /collection：返回资源对象的列表（数组）
 GET    /collection/resource：返回单个资源对象
 POST   /collection：返回新生成的资源对象
 PUT    /collection/resource：返回完整的资源对象
 PATCH  /collection/resource：返回完整的资源对象
 DELETE /collection/resource：返回一个空文档
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;发生错误时，不要返回 200 状态码&lt;/h4&gt;
&lt;p&gt;有一种不恰当的做法是，即使发生错误，也返回200状态码，把错误信息放在数据体里面，就像下面这样。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;status&quot;: &quot;failure&quot;,
  &quot;data&quot;: {
    &quot;error&quot;: &quot;Expected at least two items in list.&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;正确的做法是，状态码反映发生的错误，具体的错误信息放在数据体里面返回。下面是一个例子。&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;HTTP/1.1 400 Bad Request
Content-Type: application/json
{
  &quot;error&quot;: &quot;Invalid payoad.&quot;,
  &quot;detail&quot;: {
    &quot;surname&quot;: &quot;This field is required.&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/apifox.eVTBz1SF.svg"/><enclosure url="/_astro/apifox.eVTBz1SF.svg"/></item><item><title>Vue学习笔记（二）</title><link>https://santisify.top/blog/old/vue2</link><guid isPermaLink="true">https://santisify.top/blog/old/vue2</guid><description>组件基础，props（父组件 -&gt; 子组件），监听事件</description><pubDate>Sat, 15 Mar 2025 11:06:32 GMT</pubDate><content:encoded>&lt;h2&gt;组件基础&lt;/h2&gt;
&lt;h3&gt;组件定义&lt;/h3&gt;
&lt;p&gt;Vue组件定义在一个&lt;code&gt;.vue&lt;/code&gt;的文件中，被称为单文件组件&lt;code&gt;SFC&lt;/code&gt; :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;script setup&gt;
  import { ref } from &apos;vue&apos;

  const count = ref(0)
&amp;#x3C;/script&gt;

&amp;#x3C;template&gt;
  &amp;#x3C;button @click=&quot;count++&quot;&gt;You clicked me {{ count }} times.&amp;#x3C;/button&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;组件使用&lt;/h3&gt;
&lt;p&gt;若要使用一个子组件，需要在父组件中导入。假设我们把计数器组件放在了一个叫做 &lt;code&gt;ButtonCounter.vue&lt;/code&gt; 的文件中，这个组件将会以默认导出的形式被暴露给外部：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;script setup&gt;
  import ButtonCounter from &apos;./ButtonCounter.vue&apos;
&amp;#x3C;/script&gt;

&amp;#x3C;template&gt;
  &amp;#x3C;h1&gt;Here is a child component!&amp;#x3C;/h1&gt;
  &amp;#x3C;ButtonCounter /&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若是通过 &lt;code&gt;&amp;#x3C;script setup&gt;&lt;/code&gt; 导入的组件，可以在&lt;code&gt;&amp;#x3C;template&gt; &amp;#x3C;/template&gt;&lt;/code&gt; 中直接使用。同时，一个组件可在同一个模板中引用多次：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;ButtonCounter /&gt;
  &amp;#x3C;ButtonCounter /&gt;
  &amp;#x3C;ButtonCounter /&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于以上的示例，每个&lt;code&gt;ButtonCounter&lt;/code&gt; 组件在进行点击后不会影响其余的组件，因为每个组件都是维护自己的状态，每当我使用一个组件就新创建一个实例。&lt;/p&gt;
&lt;h3&gt;传递 props&lt;/h3&gt;
&lt;p&gt;如果我们正在构建一个博客，我们可能需要一个表示博客文章的组件。我们希望所有的博客文章分享相同的视觉布局，但有不同的内容。要实现这样的效果自然必须向组件中传递数据，例如每篇文章标题和内容，这就会使用到 props。&lt;/p&gt;
&lt;p&gt;Props 是一种特别的 attributes，你可以在组件上声明注册。要传递给博客文章组件一个标题，我们必须在组件的 props 列表上声明它。这里要用到 &lt;code&gt;defineProps&lt;/code&gt; 宏：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;!-- BlogPost.vue --&gt;
&amp;#x3C;script setup&gt;
  defineProps([&apos;title&apos;])
&amp;#x3C;/script&gt;

&amp;#x3C;template&gt;
  &amp;#x3C;h4&gt;{{ title }}&amp;#x3C;/h4&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;defineProps&lt;/code&gt;是一个仅&lt;code&gt;&amp;#x3C;script setup&gt;&lt;/code&gt;中可用的编译宏命令，并不需要显式地导入。声明的 props 会自动暴露给模板。&lt;code&gt;defineProps&lt;/code&gt;会返回一个对象，其中包含了可以传递给组件的所有 props：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const props = defineProps([&apos;title&apos;])
console.log(props.title)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一个组件可以有任意多的 props，默认情况下，所有 prop 都接受任意类型的值。
当一个 prop 被注册后，可以像这样以自定义 attribute 的形式传递数据给它：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;BlogPost title=&quot;My journey with Vue&quot; /&gt;
&amp;#x3C;BlogPost title=&quot;Blogging with Vue&quot; /&gt;
&amp;#x3C;BlogPost title=&quot;Why Vue is so fun&quot; /&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在实际应用中，我们可能在父组件中会有如下的一个博客文章数组：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const posts = ref([
  { id: 1, title: &apos;My journey with Vue&apos; },
  { id: 2, title: &apos;Blogging with Vue&apos; },
  { id: 3, title: &apos;Why Vue is so fun&apos; }
])
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种情况下，我们可以使用&lt;code&gt;v-for&lt;/code&gt;来渲染它们：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;BlogPost v-for=&quot;post in posts&quot; :key=&quot;post.id&quot; :title=&quot;post.title&quot; /&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;留意我们是如何使用&lt;code&gt;v-bind&lt;/code&gt;语法(&lt;code&gt;:title=&quot;post.title&quot;&lt;/code&gt;) 来传递动态 prop 值的。当事先不知道要渲染的确切内容时，这一点特别有用。&lt;/p&gt;
&lt;h3&gt;监听事件&lt;/h3&gt;</content:encoded><h:img src="/_astro/vue3.DOez9DA0.png"/><enclosure url="/_astro/vue3.DOez9DA0.png"/></item><item><title>Vue学习笔记（一）</title><link>https://santisify.top/blog/old/vue1</link><guid isPermaLink="true">https://santisify.top/blog/old/vue1</guid><description>语法，响应式基础，计算属性，类与样式绑定</description><pubDate>Mon, 10 Mar 2025 09:47:53 GMT</pubDate><content:encoded>&lt;p&gt;部分示例来源于&lt;a href=&quot;https://cn.vuejs.org/&quot;&gt;vuejs中文官网&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vue3对Vue2向下兼容，但部分不兼容&lt;/p&gt;
&lt;h2&gt;语法&lt;/h2&gt;
&lt;h3&gt;文本插值：&lt;/h3&gt;
&lt;p&gt;在&lt;code&gt;HTML&lt;/code&gt;中插入文本&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;HTML插值：&lt;/h3&gt;
&lt;p&gt;上述操作只能插入纯文本，可以使用&lt;code&gt;v-html&lt;/code&gt;插入&lt;code&gt;html&lt;/code&gt;文本&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;p&gt;Using v-html directive: &amp;#x3C;span v-html=&quot;rawHtml&quot;&gt;&amp;#x3C;/span&gt;&amp;#x3C;/p&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Attribute &lt;strong&gt;绑定&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;对使用的元素属性进行绑定 想响应式绑定一个Attribute,但又不能使用&lt;code&gt;{{  }}&lt;/code&gt;时,可使用&lt;code&gt;v-bind&lt;/code&gt;指令：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div v-bind:id=&quot;num&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;v-bind&lt;/code&gt;指令指示 Vue 将元素的&lt;code&gt;id&lt;/code&gt;attribute 与组件的&lt;code&gt;num&lt;/code&gt;属性保持一致。如果绑定的值是&lt;code&gt;null&lt;/code&gt;或者&lt;code&gt;undefined&lt;/code&gt;，那么该 attribute 将会从渲染的元素上移除。 简写：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :id=&quot;num&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;//点击方块后颜色切换，其中click和ref会在下面会讲到
&amp;#x3C;template&gt;
  &amp;#x3C;div style=&quot;height: 100px; width: 100px;&quot; @click=&quot;switchColor&quot; :class=&quot;str&quot;&gt;&amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;
&amp;#x3C;script setup&gt;
  import { ref } from &apos;vue&apos;

  let str = ref(&apos;su&apos;)

  function switchColor() {
    str.value = &apos;s&apos;
  }
&amp;#x3C;/script&gt;
&amp;#x3C;style scoped&gt;
  .su {
    background-color: red;
  }

  .s {
    background-color: green;
  }
&amp;#x3C;/style&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可设为bool型数据&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;button :disabled=&quot;isButtonDisabled&quot;&gt;Button&amp;#x3C;/button&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当&lt;code&gt;isButtonDisabled&lt;/code&gt;为&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Truthy&quot;&gt;真值&lt;/a&gt;或一个空字符串 (即&lt;br&gt;
&lt;code&gt;&amp;#x3C;button disabled=&quot;&quot;&gt;&lt;/code&gt;) 时，元素会包含这个&lt;code&gt;disabled&lt;/code&gt; attribute。而当其为其他&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Falsy&quot;&gt;假值&lt;/a&gt;时 attribute 将被忽略。&lt;/p&gt;
&lt;h3&gt;动态绑定多个值&lt;/h3&gt;
&lt;p&gt;如果你有像这样的一个包含多个 attribute 的 JavaScript 对象：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const objectOfAttrs = {
  id: &apos;container&apos;,
  class: &apos;wrapper&apos;,
  style: &apos;background-color:green&apos;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过不带参数的&lt;code&gt;v-bind&lt;/code&gt;，你可以将它们绑定到单个元素上：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div v-bind=&quot;objectOfAttrs&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;使用 JavaScript 表达式&lt;/h3&gt;
&lt;p&gt;至此，我们仅在模板中绑定了一些简单的属性名。但是 Vue 实际上在所有的数据绑定中都支持完整的 JavaScript 表达式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{{ number + 1 }} {{ ok ? &apos;YES&apos; : &apos;NO&apos; }} {{ message.split(&apos;&apos;).reverse().join(&apos;&apos;) }}
&amp;#x3C;div :id=&quot;`list-${id}`&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这些表达式都会被作为 JavaScript ，以当前组件实例为作用域解析执行。 在 Vue 模板内，JavaScript 表达式可以被使用在如下场景上：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在文本插值中 (双大括号)&lt;/li&gt;
&lt;li&gt;在任何 Vue 指令 (以&lt;code&gt;v-&lt;/code&gt;开头的特殊 attribute) attribute 的值中&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;仅支持表达式&lt;/h3&gt;
&lt;p&gt;每个绑定仅支持&lt;strong&gt;单一表达式&lt;/strong&gt;，也就是一段能够被求值的 JavaScript 代码。一个简单的判断方法是是否可以合法地写在&lt;code&gt;return&lt;/code&gt;后面。&lt;/p&gt;
&lt;p&gt;因此，下面的例子都是&lt;strong&gt;无效&lt;/strong&gt;的：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&amp;#x3C;!-- 这是一个语句，而非表达式 --&gt;
{
    {
        var a = 1
    }
}

&amp;#x3C;!-- 条件控制也不支持，请使用三元表达式 --&gt;
{
    {
        if (ok) {
            return message
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;a href=&quot;https://cn.vuejs.org/guide/essentials/template-syntax#calling-functions&quot;&gt;调用函数&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;可以在绑定的表达式中使用一个组件暴露的方法：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;time :title=&quot;toTitleDate(date)&quot; :datetime=&quot;date&quot;&gt; {{ formatDate(date) }} &amp;#x3C;/time&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Tip: 绑定在表达式中的方法在组件每次更新时都会被重新调用，因此&lt;strong&gt;不&lt;/strong&gt;应该产生任何副作用，比如改变数据或触发异步操作。&lt;/p&gt;
&lt;h3&gt;受限的全局访问&lt;/h3&gt;
&lt;p&gt;模板中的表达式将被沙盒化，仅能够访问到有限的全局对象列表。该列表中会暴露常用的内置全局对象，比如&lt;code&gt;Math&lt;/code&gt;和&lt;code&gt;Date&lt;/code&gt;。 没有显式包含在列表中的全局对象将不能在模板内表达式中访问，例如用户附加在&lt;code&gt;window&lt;/code&gt;上的属性。然而，你也可以自行在&lt;code&gt;app.config.globalProperties&lt;/code&gt;上显式地添加它们，供所有的 Vue 表达式使用。&lt;/p&gt;
&lt;h2&gt;响应式基础&lt;/h2&gt;
&lt;h3&gt;ref()&lt;/h3&gt;
&lt;p&gt;组合式API中,使用&lt;code&gt;ref()&lt;/code&gt;函数声明响应式状态&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { ref } from &apos;vue&apos;

const num = ref(100)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;ref()&lt;/code&gt;接收参数，并将其包裹在一个带有&lt;code&gt;.value&lt;/code&gt;属性的 &lt;code&gt;ref&lt;/code&gt; 对象中返回 所以&lt;code&gt;vue&lt;/code&gt;中的&lt;code&gt;js&lt;/code&gt;需要使用组合式&lt;code&gt;setup()&lt;/code&gt;，并且在使用时需要添加上&lt;code&gt;.value&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;button @click=&quot;increment&quot;&gt;{{ count }}&amp;#x3C;/button&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;script setup&gt;
  import { ref } from &apos;vue&apos;

  const count = ref(0)

  function increment() {
    count.value++
  }
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;vue2&lt;/code&gt;中使用&lt;code&gt;set()&lt;/code&gt;实现响应式，而在&lt;code&gt;vue3&lt;/code&gt;中使用&lt;code&gt;ref()&lt;/code&gt;，并且&lt;code&gt;vue3&lt;/code&gt;不兼容&lt;code&gt;set()&lt;/code&gt;函数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;深层响应性&lt;/h3&gt;
&lt;p&gt;Ref 可以持有任何类型的值，包括深层嵌套的对象、数组或者 JavaScript 内置的数据结构，比如&lt;code&gt;Map&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Ref 会使它的值具有深层响应性。这意味着即使改变嵌套对象或数组时，变化也会被检测到：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { ref } from &apos;vue&apos;

const obj = ref({
  nested: { count: 0 },
  arr: [&apos;foo&apos;, &apos;bar&apos;]
})

function mutateDeeply() {
  // 以下都会按照期望工作
  obj.value.nested.count++
  obj.value.arr.push(&apos;baz&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;reactive()&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;reactive()&lt;/code&gt;是响应式的另一种&lt;strong&gt;API&lt;/strong&gt;，&lt;code&gt;reactive()&lt;/code&gt;可使对象本身具有响应性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { reactive } from &apos;vue&apos;

const state = reactive({ count: 0 })
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;template&lt;/code&gt;中以下方式使用：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;button @click=&quot;state.cnt ++&quot;&gt;{{ state.cnt }}&amp;#x3C;/button&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;计算属性&lt;/h2&gt;
&lt;h3&gt;基础示例&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;span&gt;{{ author.books.length &gt; 0 ? &quot;YES&quot; : &quot;NO&quot; }}&amp;#x3C;/span&gt;
&amp;#x3C;/template&gt;

&amp;#x3C;script setup&gt;
  import { reactive } from &apos;vue&apos;

  const author = reactive({
    name: &apos;John Doe&apos;,
    books: [&apos;Vue 2 - Advanced Guide&apos;, &apos;Vue 3 - Basic Guide&apos;, &apos;Vue 4 - The Mystery&apos;]
  })
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述示例中，可以发现计算是依靠&lt;code&gt;author.books&lt;/code&gt;的大小确定的，如果我在模板中多次使用这样的判断，是否显得过于臃肿。&lt;br&gt;
对于这样的判断可以引入&lt;code&gt;computed()&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;computed()&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;script setup&gt;
  import { computed, reactive } from &apos;vue&apos;

  const author = reactive({
    name: &apos;John Doe&apos;,
    books: [&apos;Vue 2 - Advanced Guide&apos;, &apos;Vue 3 - Basic Guide&apos;, &apos;Vue 4 - The Mystery&apos;]
  })

  // 一个计算属性 ref
  const publishedBooksMessage = computed(() =&gt; {
    return author.books.length &gt; 0 ? &apos;Yes&apos; : &apos;No&apos;
  })
&amp;#x3C;/script&gt;

&amp;#x3C;template&gt;
  &amp;#x3C;p&gt;Has published books:&amp;#x3C;/p&gt;
  &amp;#x3C;span&gt;{{ publishedBooksMessage }}&amp;#x3C;/span&gt;
&amp;#x3C;/template&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们在这里定义了一个计算属性&lt;code&gt;publishedBooksMessage&lt;/code&gt;。&lt;code&gt;computed()&lt;/code&gt;&lt;br&gt;
方法期望接收一个&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/get#description&quot;&gt;getter 函数&lt;/a&gt;&lt;br&gt;
，返回值为一个&lt;strong&gt;计算属性 ref&lt;/strong&gt;。和其他一般的 ref 类似，你可以通过&lt;code&gt;publishedBooksMessage.value&lt;/code&gt;访问计算结果。计算属性 ref&lt;br&gt;
也会在模板中自动解包，因此在模板表达式中引用时无需添加&lt;code&gt;.value&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Vue 的计算属性会自动追踪响应式依赖。它会检测到&lt;code&gt;publishedBooksMessage&lt;/code&gt;依赖于&lt;code&gt;author.books&lt;/code&gt;，所以当&lt;code&gt;author.books&lt;/code&gt;改变时，任何依赖于&lt;br&gt;
&lt;code&gt;publishedBooksMessage&lt;/code&gt;的绑定都会同时更新。&lt;/p&gt;
&lt;h3&gt;可写计算属性&lt;/h3&gt;
&lt;p&gt;计算属性默认是只读的。当你尝试修改一个计算属性时，你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性，你可以通过同时提供&lt;br&gt;
getter 和 setter 来创建：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;&amp;#x3C;template&gt;
    {{fullName}}
&amp;#x3C;/template&gt;
&amp;#x3C;script setup&gt;
    import {ref, computed} from &apos;vue&apos;

    const firstName = ref(&apos;John&apos;)
    const lastName = ref(&apos;Doe&apos;)

    const fullName = computed({
    // getter
    get() {
    return firstName.value + &apos; &apos; + lastName.value
},
    // setter
    set(newValue) {
    // 注意：我们这里使用的是解构赋值语法
    [firstName.value, lastName.value] = newValue.split(&apos; &apos;)
}})

    console.log(fullName.value, firstName.value, lastName.value);

    fullName.value = &quot;Jack Doe&quot;;

    console.log(fullName.value, firstName.value, lastName.value);
&amp;#x3C;/script&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述示例中，当运行&lt;code&gt;fullName.value = &quot;Jack Doe&quot;;&lt;/code&gt;时，&lt;code&gt;firstName&lt;/code&gt;和&lt;code&gt;lastName&lt;/code&gt;也会随之更新。&lt;/p&gt;
&lt;h2&gt;类与样式绑定&lt;/h2&gt;
&lt;h3&gt;绑定HTML class&lt;/h3&gt;
&lt;h4&gt;绑定对象&lt;/h4&gt;
&lt;p&gt;绑定对象一般使用&lt;code&gt;v-bind&lt;/code&gt;，比如绑定&lt;code&gt;class&lt;/code&gt;一般写为&lt;code&gt;v-bind:class&lt;/code&gt; 简写为&lt;code&gt;:class&lt;/code&gt;,对其传递对象可动态切换class：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :class=&quot;{ active: isActive }&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中class的&lt;code&gt;active&lt;/code&gt;是否存在由&lt;code&gt;isActive&lt;/code&gt;的真值来确定。&lt;br&gt;
对象中可通过多个字段class对象&lt;br&gt;
例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;div class=&quot;static&quot; :class=&quot;{ active: isActive, &apos;text-danger&apos;: hasError }&quot;&gt;123&amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;
&amp;#x3C;script setup&gt;
  import { ref } from &apos;vue&apos;

  const isActive = ref(true)
  const hasError = ref(false)
&amp;#x3C;/script&gt;

&amp;#x3C;style scoped&gt;
  .text-danger {
    color: red;
  }
&amp;#x3C;/style&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在上述示例中，字段&lt;code&gt;active, hasError&lt;/code&gt; 的真值影响在class类中是否存在对应的类名。当&lt;code&gt;hasError&lt;/code&gt;为真时，由于css中的&lt;code&gt;text-danger&lt;/code&gt;&lt;br&gt;
样式，会将字体&lt;strong&gt;123&lt;/strong&gt;改变为红色。&lt;br&gt;
上述示例渲染后的效果如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div class=&quot;static active&quot;&gt;123&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过以上，我们可以对&lt;code&gt;：class&lt;/code&gt;传入一个对象&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;template&gt;
  &amp;#x3C;div class=&quot;static&quot; :class=&quot;obj&quot;&gt;123&amp;#x3C;/div&gt;
&amp;#x3C;/template&gt;
&amp;#x3C;script setup&gt;
  import { reactive } from &apos;vue&apos;

  const obj = reactive({
    active: true,
    &apos;text-danger&apos;: false
  })
&amp;#x3C;/script&gt;

&amp;#x3C;style scoped&gt;
  .text-danger {
    color: red;
  }
&amp;#x3C;/style&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;传入对象方法渲染后的效果同上，个人较为喜欢多个字段操作&lt;/p&gt;
&lt;p&gt;我们也可以绑定一个返回对象的[[#计算属性]]。这是一个常见且很有用的技巧：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const isActive = ref(true)
const error = ref(null)

const obj = computed(() =&gt; ({
  active: isActive.value &amp;#x26;&amp;#x26; !error.value,
  &apos;text-danger&apos;: error.value &amp;#x26;&amp;#x26; error.value.type === &apos;fatal&apos;
}))
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :class=&quot;classObject&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;绑定数组&lt;/h4&gt;
&lt;p&gt;我们可以给&lt;code&gt;:class&lt;/code&gt;绑定一个数组来渲染多个 CSS class：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const activeClass = ref(&apos;active&apos;)
const errorClass = ref(&apos;text-danger&apos;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :class=&quot;[activeClass, errorClass]&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染的结果是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div class=&quot;active text-danger&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你也想在数组中有条件地渲染某个 class，你可以使用三元表达式：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :class=&quot;[isActive ? activeClass : &apos;&apos;, errorClass]&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;errorClass&lt;/code&gt;会一直存在，但&lt;code&gt;activeClass&lt;/code&gt;只会在&lt;code&gt;isActive&lt;/code&gt;为真时才存在。&lt;/p&gt;
&lt;p&gt;然而，这可能在有多个依赖条件的 class 时会有些冗长。因此也可以在数组中嵌套对象：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :class=&quot;[{ [activeClass]: isActive }, errorClass]&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;在组件上使用&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;本节假设你已经有&lt;a href=&quot;https://cn.vuejs.org/guide/essentials/component-basics.html&quot;&gt;Vue 组件&lt;/a&gt;的知识基础。如果没有，你也可以暂时跳过，以后再阅读。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对于只有一个根元素的组件，当你使用了&lt;code&gt;class&lt;/code&gt;attribute 时，这些 class 会被添加到根元素上并与该元素上已有的 class 合并。&lt;/p&gt;
&lt;p&gt;举例来说，如果你声明了一个组件名叫&lt;code&gt;MyComponent&lt;/code&gt;，模板如下：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;!-- 子组件模板 --&gt;
&amp;#x3C;p class=&quot;foo bar&quot;&gt;Hi!&amp;#x3C;/p&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在使用时添加一些 class：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;!-- 在使用组件时 --&gt;
&amp;#x3C;MyComponent class=&quot;baz boo&quot; /&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;渲染出的 HTML 为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;p class=&quot;foo bar baz boo&quot;&gt;Hi!&amp;#x3C;/p&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Class 的绑定也是同样的：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;MyComponent :class=&quot;{ active: isActive }&quot; /&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当&lt;code&gt;isActive&lt;/code&gt;为真时，被渲染的 HTML 会是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;p class=&quot;foo bar active&quot;&gt;Hi!&amp;#x3C;/p&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你的组件有多个根元素，你将需要指定哪个根元素来接收这个 class。你可以通过组件的&lt;code&gt;$attrs&lt;/code&gt;属性来指定接收的元素：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;!-- MyComponent 模板使用 $attrs 时 --&gt;
&amp;#x3C;p :class=&quot;$attrs.class&quot;&gt;Hi!&amp;#x3C;/p&gt;
&amp;#x3C;span&gt;This is a child component&amp;#x3C;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;MyComponent class=&quot;baz&quot; /&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这将被渲染为：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;p class=&quot;baz&quot;&gt;Hi!&amp;#x3C;/p&gt;
&amp;#x3C;span&gt;This is a child component&amp;#x3C;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你可以在透传 Attribute一章中了解更多组件的 attribute 继承的细节。&lt;/p&gt;
&lt;h3&gt;绑定内联样式&lt;/h3&gt;
&lt;h4&gt;绑定对象&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;:style&lt;/code&gt;支持绑定 JavaScript 对象值，对应的是HTML 元素的&lt;code&gt;style&lt;/code&gt;属性：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const activeColor = ref(&apos;red&apos;)
const fontSize = ref(30)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :style=&quot;{ color: activeColor, fontSize: fontSize + &apos;px&apos; }&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;尽管推荐使用 camelCase，但&lt;code&gt;:style&lt;/code&gt;也支持 kebab-cased 形式的 CSS 属性 key (对应其 CSS 中的实际名称)，例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :style=&quot;{ &apos;font-size&apos;: fontSize + &apos;px&apos; }&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;直接绑定一个样式对象通常是一个好主意，这样可以使模板更加简洁：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;const styleObject = reactive({
  color: &apos;red&apos;,
  fontSize: &apos;30px&apos;
})
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :style=&quot;styleObject&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;同样的，如果样式对象需要更复杂的逻辑，也可以使用返回样式对象的计算属性。&lt;/p&gt;
&lt;h4&gt;绑定数组&lt;/h4&gt;
&lt;p&gt;我们还可以给&lt;code&gt;:style&lt;/code&gt;绑定一个包含多个样式对象的数组。这些对象会被合并后渲染到同一元素上：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :style=&quot;[baseStyles, overridingStyles]&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;自动前缀&lt;/h4&gt;
&lt;p&gt;当你在&lt;code&gt;:style&lt;/code&gt;中使用了需要&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Vendor_Prefix&quot;&gt;浏览器特殊前缀&lt;/a&gt;的 CSS&lt;br&gt;
属性时，Vue 会自动为他们加上相应的前缀。Vue 是在运行时检查该属性是否支持在当前浏览器中使用。如果浏览器不支持某个属性，那么将尝试加上各个浏览器特殊前缀，以找到哪一个是被支持的。&lt;/p&gt;
&lt;h4&gt;样式多值&lt;/h4&gt;
&lt;p&gt;你可以对一个样式属性提供多个 (不同前缀的) 值，举例来说：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;#x3C;div :style=&quot;{ display: [&apos;-webkit-box&apos;, &apos;-ms-flexbox&apos;, &apos;flex&apos;] }&quot;&gt;&amp;#x3C;/div&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;数组仅会渲染浏览器支持的最后一个值。在这个示例中，在支持不需要特别前缀的浏览器中都会渲染为&lt;code&gt;display: flex&lt;/code&gt;。&lt;/p&gt;</content:encoded><h:img src="/_astro/vue3.DOez9DA0.png"/><enclosure url="/_astro/vue3.DOez9DA0.png"/></item><item><title>LaTex</title><link>https://santisify.top/blog/old/latex</link><guid isPermaLink="true">https://santisify.top/blog/old/latex</guid><description>LaTex 下书写数学公式、表达式以及各种数学符号</description><pubDate>Thu, 13 Feb 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;LaTex 下书写数学公式、表达式以及各种数学符号&lt;/h1&gt;
&lt;h2&gt;Table of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#orgf4fa175&quot;&gt;什么是 LaTex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org69cb57c&quot;&gt;如何使用 Latex 写数学符号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#orga792cdd&quot;&gt;数学符号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#orgd29656b&quot;&gt;Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org56443c6&quot;&gt;希腊字母&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org7b3d713&quot;&gt;向量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org2bda6eb&quot;&gt;集合&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#orge64023a&quot;&gt;逻辑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org6272b34&quot;&gt;微积分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org7a11eae&quot;&gt;三角函数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org332d9aa&quot;&gt;其他&lt;/a&gt;
_ &lt;a href=&quot;#orgd675dc2&quot;&gt;cases&lt;/a&gt;
_ &lt;a href=&quot;#org19b1b02&quot;&gt;公式换行、对齐&lt;/a&gt;
_ &lt;a href=&quot;#org1138c42&quot;&gt;substack&lt;/a&gt;
_ &lt;a href=&quot;#orgdcee25d&quot;&gt;matrix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org2eaa390&quot;&gt;最后&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#org83a746c&quot;&gt;Ref:&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;什么是 LaTex&lt;/h2&gt;
&lt;p&gt;Latex 是一个用于书写以及排版的计算机语言。它在写数学符号和公式方面尤其方便。&lt;/p&gt;
&lt;h2&gt;如何使用 Latex 写数学符号&lt;/h2&gt;
&lt;p&gt;在 Latex 中有三种方法来写数学符号：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;行内(inline)形式（符号以及公式夹杂在文本的中间，例如这样 \(E=mc^2\) ）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;独立的一行(equation)&lt;/p&gt;
&lt;p&gt;\begin{equation} x=\frac{-b\pm\sqrt{b^2-4ac}}{2a} \end{equation}&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;full-sized 行内表达式（通过 displaystyle） 为了得到这种形式的表达式需要使用 \displaystyle。 例如： &lt;code&gt;I want this $\displaystyle \sum_{n=1}^{\infty}\frac{1}{n}$ ,not this $\sum_{n=1}^{\infty} \frac{1}{n}&lt;/code&gt;, I want this \(\displaystyle \sum_{n=1}^{\infty}\frac{1}{n}\) ,not this \(\sum_{n=1}^{\infty} \frac{1}{n}\) 。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;数学符号&lt;/h2&gt;
&lt;p&gt;下面是比较常用的一些：&lt;/p&gt;
&lt;p&gt;| 描述                     | 命令              | 输出                    |
| ------------------------ | ----------------- | ----------------------- |
| addition                 | +                 | \(+\)                 |
| subtraction              | -                | \(-\)                 |
| plus or minus            | &lt;code&gt;\pm&lt;/code&gt;             | \(\pm\)              |
| multiplication(times)    | &lt;code&gt;\times&lt;/code&gt;          | \(\times\)           |
| multiplication(dot)      | &lt;code&gt;\cdot&lt;/code&gt;           | \(cdot\)              |
| division symbol          | &lt;code&gt;\div&lt;/code&gt;            | \(\div\)             |
| division(slash)          | &lt;code&gt;/&lt;/code&gt;               | \(/\)                 |
| simple text              | &lt;code&gt;\text{text}&lt;/code&gt;     | \(\text{text}\)      |
| infinity                 | &lt;code&gt;\infty&lt;/code&gt;          | \(\infty\)           |
| dots                     | &lt;code&gt;1,2,3,\ldots&lt;/code&gt;    | \(1,2,3,\ldots\)     |
| dots                     | &lt;code&gt;1+2+3+\cdots&lt;/code&gt;    | \(1+2+3+\cdots\)     |
| fraction                 | &lt;code&gt;\frac{a}{b}&lt;/code&gt;     | \(\frac{a}{b}\)      |
| nth root                 | &lt;code&gt;\sqrt[n]{x}&lt;/code&gt;     | \(\sqrt[n]{x}\)    |
| square root              | &lt;code&gt;\sqrt{x}&lt;/code&gt;        | \(\sqrt{x}\)         |
| exponentiation           | &lt;code&gt;a^b&lt;/code&gt;             | \(a^b\)               |
| subscript                | &lt;code&gt;a_b&lt;/code&gt;             | \(a_b\)               |
| natural log              | &lt;code&gt;\ln(x)&lt;/code&gt;          | \(\ln(x)\)           |
| logarithms               | &lt;code&gt;\log_{a}b&lt;/code&gt;       | \(\log_{a}b\)       |
| exp                      | &lt;code&gt;\exp&lt;/code&gt;            | \(\exp\)             |
| deg                      | &lt;code&gt;\deg(f)&lt;/code&gt;         | \(deg(f)\)            |
| arcmin                   | &lt;code&gt;^\prime&lt;/code&gt;         | \(^\prime\)          |
| arcsec                   | &lt;code&gt;^{\prime\prime}&lt;/code&gt; | \(^{\prime\prime}\) |
| circle plus              | &lt;code&gt;\oplus&lt;/code&gt;          | \(\oplus\)           |
| circle times             | &lt;code&gt;\otimes&lt;/code&gt;         | \(\otimes\)          |
| equal                    | =                | \(=\)                 |
| not equal                | &lt;code&gt;\ne&lt;/code&gt;             | \(\ne\)              |
| less than                | &lt;code&gt;&amp;#x3C;&lt;/code&gt;               | \(&amp;#x3C;\)                 |
| less than or equal to    | &lt;code&gt;\le&lt;/code&gt;             | \(\le\)              |
| greater than or equal to | &lt;code&gt;\ge&lt;/code&gt;             | \(\ge\)              |
| approximately equal to   | &lt;code&gt;\approx&lt;/code&gt;         | \(\approx\)          |&lt;/p&gt;
&lt;h2&gt;Functions&lt;/h2&gt;
&lt;p&gt;| 描述        | 命令    | 输出         |
| ----------- | ------- | ------------ |
| maps to     | &lt;code&gt;\to&lt;/code&gt;   | \(\to\)   |
| composition | &lt;code&gt;\circ&lt;/code&gt; | \(\circ\) |&lt;/p&gt;
&lt;h2&gt;希腊字母&lt;/h2&gt;
&lt;p&gt;| 命令          | 输出               | 命令       | 输出            |
| ------------- | ------------------ | ---------- | --------------- |
| &lt;code&gt;\alpha&lt;/code&gt;      | \(\alpha\)      | &lt;code&gt;\tau&lt;/code&gt;     | \(\tau\)     |
| &lt;code&gt;\beta&lt;/code&gt;       | \(\beta\)       | &lt;code&gt;\theta&lt;/code&gt;   | \(\theta\)   |
| &lt;code&gt;\chi&lt;/code&gt;        | \(\chi\)        | &lt;code&gt;\upsilon&lt;/code&gt; | \(\upsilon\) |
| &lt;code&gt;\delta&lt;/code&gt;      | \(\delta\)      | &lt;code&gt;\xi&lt;/code&gt;      | \(\xi\)      |
| &lt;code&gt;\epsilon&lt;/code&gt;    | \(\epsilon\)    | &lt;code&gt;\zeta&lt;/code&gt;    | \(\zeta\)    |
| &lt;code&gt;\varepsilon&lt;/code&gt; | \(\varepsilon\) | &lt;code&gt;\Delta&lt;/code&gt;   | \(\Delta\)   |
| &lt;code&gt;\eta&lt;/code&gt;        | \(\eta\)        | &lt;code&gt;\Gamma&lt;/code&gt;   | \(\Gamma\)   |
| &lt;code&gt;\gamma&lt;/code&gt;      | \(\gamma\)      | &lt;code&gt;Lambda&lt;/code&gt;   | \(\Lambda\)  |
| &lt;code&gt;\iota&lt;/code&gt;       | \(\iota\)       | &lt;code&gt;\Omega&lt;/code&gt;   | \(\Omega\)   |
| &lt;code&gt;\kappa&lt;/code&gt;      | \(\kappa\)      | &lt;code&gt;\Phi&lt;/code&gt;     | \(\Phi\)     |
| &lt;code&gt;lambda&lt;/code&gt;      | \(\lambda\)     | &lt;code&gt;\Pi&lt;/code&gt;      | \(\Pi\)      |
| &lt;code&gt;\mu&lt;/code&gt;         | \(\mu\)         | &lt;code&gt;\Psi&lt;/code&gt;     | \(\Psi\)     |
| &lt;code&gt;\nu&lt;/code&gt;         | \(\nu\)         | &lt;code&gt;Sigma&lt;/code&gt;    | \(\Sigma\)   |
| &lt;code&gt;\omega&lt;/code&gt;      | \(\omega\)      | &lt;code&gt;\Theta&lt;/code&gt;   | \(Theta\)     |
| &lt;code&gt;\phi&lt;/code&gt;        | \(\phi\)        | &lt;code&gt;\Upsilon&lt;/code&gt; | \(\Upsilon\) |
| &lt;code&gt;\varphi&lt;/code&gt;     | \(\varphi\)     | &lt;code&gt;\Xi&lt;/code&gt;      | \(\Xi\)      |
| &lt;code&gt;\pi&lt;/code&gt;         | \(\pi\)         | &lt;code&gt;\aleph&lt;/code&gt;   | \(\aleph\)   |
| &lt;code&gt;\psi&lt;/code&gt;        | \(\psi\)        | &lt;code&gt;\beth&lt;/code&gt;    | \(\beth\)    |
| &lt;code&gt;\rho&lt;/code&gt;        | \(\rho\)        | &lt;code&gt;\daleth&lt;/code&gt;  | \(\daleth\)  |
| &lt;code&gt;\sigma&lt;/code&gt;      | \(\sigma\)      | &lt;code&gt;\gimel&lt;/code&gt;   | \(\gimel\)   |&lt;/p&gt;
&lt;h2&gt;向量&lt;/h2&gt;
&lt;p&gt;| 描述   | 命令         | 输出              |
| ------ | ------------ | ----------------- |
| vector | &lt;code&gt;\vec{v}&lt;/code&gt;    | \(\vec{v}\)    |
| vector | &lt;code&gt;\mathbf{v}&lt;/code&gt; | \(\mathbf{v}\) |&lt;/p&gt;
&lt;h2&gt;集合&lt;/h2&gt;
&lt;p&gt;| 描述                | 命令                    | 输出                          |
| ------------------- | ----------------------- | ----------------------------- |
| set brackets        | &lt;code&gt;\{1,2,3\}&lt;/code&gt;             | \(\{1,2,3\}\)             |
| element of          | &lt;code&gt;\in&lt;/code&gt;                   | \(\in\)                    |
| subset of           | &lt;code&gt;\subset&lt;/code&gt;               | \(\subset\)                |
| subset of           | &lt;code&gt;\subseteq&lt;/code&gt;             | \(\subseteq\)              |
| contains            | &lt;code&gt;\supset&lt;/code&gt;               | \(\supset\)                |
| contains            | &lt;code&gt;\supseteq&lt;/code&gt;             | \(\supseteq\)              |
| union               | &lt;code&gt;\cup&lt;/code&gt;                  | \(\cup\)                   |
| intersection        | &lt;code&gt;\cap&lt;/code&gt;                  | \(\cap\)                   |
| big union           | &lt;code&gt;\bigcup_{n=1}^{10}A_n&lt;/code&gt; | \(\bigcup_{n=1}^{10}A_n\) |
|                     | &lt;code&gt;\bigcap_{n=1}^{10}A_n&lt;/code&gt; | \(\bigcap_{n=1}^{10}A_n\) |
|                     | &lt;code&gt;\emptyset&lt;/code&gt;             | \(\emptyset\)              |
|                     | &lt;code&gt;\mathcal{P}&lt;/code&gt;           | \(\mathcal{P}\)            |
|                     | &lt;code&gt;\min&lt;/code&gt;                  | \(\min\)                   |
|                     | &lt;code&gt;\max&lt;/code&gt;                  | \(\max\)                   |
|                     | &lt;code&gt;\sup&lt;/code&gt;                  | \(\sup\)                   |
|                     | &lt;code&gt;\inf&lt;/code&gt;                  | \(\inf\)                   |
|                     | &lt;code&gt;\limsup&lt;/code&gt;               | \(\limsup\)                |
|                     | &lt;code&gt;\liminf&lt;/code&gt;               | \(\liminf\)                |
|                     | &lt;code&gt;\overline{A}&lt;/code&gt;          | \(\overline{A}\)           |
| Set of real numbers | &lt;code&gt;\mathbb{R}&lt;/code&gt;            | \(\mathbb{R}\)             |
|                     |                         |                               |&lt;/p&gt;
&lt;h2&gt;逻辑&lt;/h2&gt;
&lt;p&gt;| 描述           | 命令              | 输出                   |
| -------------- | ----------------- | ---------------------- |
| not            | &lt;code&gt;\sim&lt;/code&gt;            | \(\sim\)            |
| and            | &lt;code&gt;\land&lt;/code&gt;           | \(\land\)           |
| or             | &lt;code&gt;\lor&lt;/code&gt;            | \(\lor\)            |
| if..then       | &lt;code&gt;\to&lt;/code&gt;             | \(\to\)             |
| if and only if | &lt;code&gt;\leftrightarrow&lt;/code&gt; | \(\leftrightarrow\) |
| logical eq     | &lt;code&gt;\equiv&lt;/code&gt;          | \(\equiv\)          |
| therefore      | ∴                 | \(\therefore\)      |
| there exists   | &lt;code&gt;\exists&lt;/code&gt;         | \(\exists\)         |
| for all        | &lt;code&gt;\forall&lt;/code&gt;         | \(\forall\)         |
| implies        | &lt;code&gt;\Rightarrow&lt;/code&gt;     | \(\Rightarrow\)     |
| equivalent     | &lt;code&gt;\Leftrightarrow&lt;/code&gt; | \(\Leftrightarrow\) |&lt;/p&gt;
&lt;h2&gt;微积分&lt;/h2&gt;
&lt;p&gt;| 描述               | 命令                             | 输出                                    |
| ------------------ | -------------------------------- | --------------------------------------- |
| derivative         | &lt;code&gt;\frac{df}{dx}&lt;/code&gt;                  | \(\frac{df}{dx}\)                    |
| derivative         | &lt;code&gt;f&apos;&lt;/code&gt;                             | \(f&apos;\)                                |
| partial derivative | &lt;code&gt;\frac{\partial f} {\partial x}&lt;/code&gt; | \(\frac{\partial f} {\partial x}\) |
| limits             | &lt;code&gt;\lim_{x\to \infty}&lt;/code&gt;             | \(\lim_{x\to \infty}\)            |
| sum                | &lt;code&gt;\sum_{n=1}^{\infty}a_n&lt;/code&gt;         | \(\sum_{n=1}^{\infty}a_n\)         |
| product            | &lt;code&gt;\prod_{n=1}^{\infty}a_n&lt;/code&gt;        | \(\prod_{n=1}^{\infty}a_n\)        |
| integral           | &lt;code&gt;\int&lt;/code&gt;                           | \(\int\)                             |
|                    | &lt;code&gt;\iint&lt;/code&gt;                          | \(\iint\)                            |
|                    | &lt;code&gt;\iiint&lt;/code&gt;                         | \(\iiint\)                           |&lt;/p&gt;
&lt;h2&gt;三角函数&lt;/h2&gt;
&lt;p&gt;| 描述 | 命令            | 输出                 |
| ---- | --------------- | -------------------- |
|      | &lt;code&gt;\angle ABC&lt;/code&gt;    | \(\angle ABC\)    |
|      | &lt;code&gt;90^{\circ}&lt;/code&gt;    | \(90^{\circ}\)    |
|      | &lt;code&gt;\triangle ABC&lt;/code&gt; | \(\triangle ABC\) |
|      | &lt;code&gt;\overline{AB}&lt;/code&gt; | \(\overline{AB}\) |
|      | &lt;code&gt;\sin&lt;/code&gt;          | \(\sin\)          |
|      | &lt;code&gt;\cos&lt;/code&gt;          | \(\cos\)          |
|      | &lt;code&gt;\tan&lt;/code&gt;          | \(\tan\)          |
|      | &lt;code&gt;\cot&lt;/code&gt;          | \(\cot\)          |
|      | &lt;code&gt;\sec&lt;/code&gt;          | \(\sec\)          |
|      | &lt;code&gt;\csc&lt;/code&gt;          | \(\csc\)          |
|      | &lt;code&gt;\arcsin&lt;/code&gt;       | \(\arcsin\)       |
|      | &lt;code&gt;\arccos&lt;/code&gt;       | \(\arccos\)       |
|      | &lt;code&gt;\arctan&lt;/code&gt;       | \(\arctan\)       |&lt;/p&gt;
&lt;h2&gt;其他&lt;/h2&gt;
&lt;p&gt;| 描述       | 命令                                | 输出                                        |
| ---------- | ----------------------------------- | ------------------------------------------- |
| underbrace | &lt;code&gt;\underbrace{}_{}&lt;/code&gt;                  | \(\underbrace{}_i\)                     |
| boxed      | &lt;code&gt;\boxed&lt;/code&gt;                            | \(\boxed{\frac {a} {b}}\)               |
| hat        | &lt;code&gt;\hat{}&lt;/code&gt;                            | \(\hat{\theta}\)                        |
|            | &lt;code&gt;\widehat{d e f}&lt;/code&gt;                   | \(\widehat{d e f}\)                      |
| overbrace  | &lt;code&gt;\overbrace{}^{}&lt;/code&gt;                   | \(\overbrace{ 1+2+\cdots+100 }^{5050}\) |
|            | &lt;code&gt;\binom{n}{k}&lt;/code&gt;                      | \(\binom{n}{k}\)                         |
|            | &lt;code&gt;op\stackrel{a}{\longrightarrow}op&lt;/code&gt; | \(op\stackrel{a}{\longrightarrow}op\)   |&lt;/p&gt;
&lt;p&gt;\binom{n}{k} \end{equation}&lt;/p&gt;
&lt;h3&gt;cases&lt;/h3&gt;
&lt;p&gt;写法：&lt;/p&gt;
&lt;p&gt;\begin{equation}
F= \begin{cases} a &amp;#x26; {b=0}\\ c &amp;#x26; {d=1} \end{cases}
\end{equation}&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;\begin{equation} F= \begin{cases} a &amp;#x26; {b=0}\\ c &amp;#x26; {d=1} \end{cases} \end{equation}&lt;/p&gt;
&lt;p&gt;或者这种写法：&lt;/p&gt;
&lt;p&gt;f(n) =
\begin{cases}
n/2, &amp;#x26; \mbox{if }n\mbox{ is even} \\
3n+1, &amp;#x26; \mbox{if }n\mbox{ is odd}
\end{cases}&lt;/p&gt;
&lt;h3&gt;公式换行、对齐&lt;/h3&gt;
&lt;p&gt;写法：&lt;/p&gt;
&lt;p&gt;\begin{align}
F &amp;#x26;= a + b \\&amp;#x26;=c+d \\&amp;#x26;=e+f
\end{align}&lt;/p&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;\begin{align} F &amp;#x26;= a + b \\&amp;#x26;=c+d \\&amp;#x26;=e+f \end{align}&lt;/p&gt;
&lt;p&gt;关键是 align, &amp;#x26; 用于对齐， \\用于换行&lt;/p&gt;
&lt;h3&gt;substack&lt;/h3&gt;
&lt;p&gt;\begin{equation}
\sum_{\substack{-m \le j \le +m \\ j \ne 0}}
\end{equation}&lt;/p&gt;
&lt;p&gt;使限制条件处于并列的两行：&lt;/p&gt;
&lt;p&gt;\begin{equation} \sum_{\substack{-m \le j \le +m \\ j \ne 0}} \end{equation}&lt;/p&gt;
&lt;h3&gt;matrix&lt;/h3&gt;
&lt;p&gt;\begin{vmatrix}
x &amp;#x26; y \\
z &amp;#x26; v
\end{vmatrix}&lt;/p&gt;
&lt;p&gt;\begin{equation} \begin{vmatrix} x &amp;#x26; y \\ z &amp;#x26; v \end{vmatrix} \end{equation}&lt;/p&gt;
&lt;p&gt;\begin{Vmatrix}
x &amp;#x26; y \\
z &amp;#x26; v
\end{Vmatrix}&lt;/p&gt;
&lt;p&gt;\begin{equation} \begin{Vmatrix} x &amp;#x26; y \\ z &amp;#x26; v \end{Vmatrix} \end{equation}&lt;/p&gt;
&lt;p&gt;\begin{pmatrix}
x &amp;#x26; y \\
z &amp;#x26; v
\end{pmatrix}&lt;/p&gt;
&lt;p&gt;\begin{equation} \begin{pmatrix} x &amp;#x26; y \\ z &amp;#x26; v \end{pmatrix} \end{equation}&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;如果是写一些笔记或者论文中有大量数学符号，我推荐使用 Org mode 来写， 真的非常非常方便，如果你体验过一次就会知道。对很多人来说，这个其实门槛有点高了，因为你必须要对 Emacs 有所熟悉才行。 Org mode 下原生支持的符号可参考：&lt;a href=&quot;https://orgmode.org/worg/org-symbols.html&quot;&gt;Symbols in Org-mode&lt;/a&gt; 。&lt;/p&gt;
&lt;h2&gt;Ref:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.authorea.com/users/77723/articles/110898-how-to-write-mathematical-equations-expressions-and-symbols-with-latex-a-cheatsheet&quot;&gt;https://www.authorea.com/users/77723/articles/110898-how-to-write-mathematical-equations-expressions-and-symbols-with-latex-a-cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://chem.libretexts.org/Courses/Remixer_University/Construction_Guide/3:_Advanced_Editing/3.3B:_LaTeX//MathJax_Examples&quot;&gt;https://chem.libretexts.org/Courses/Remixer_University/Construction_Guide/3:_Advanced_Editing/3.3B:_LaTeX//MathJax_Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><h:img src="/_astro/LaTeX_project_logo_bird.BLEtteOF.svg"/><enclosure url="/_astro/LaTeX_project_logo_bird.BLEtteOF.svg"/></item><item><title>Codeforces Round 1002 (Div.2)</title><link>https://santisify.top/blog/old/cf2059</link><guid isPermaLink="true">https://santisify.top/blog/old/cf2059</guid><description>codeforces-round-1002(A-D)</description><pubDate>Fri, 07 Feb 2025 14:08:54 GMT</pubDate><content:encoded>&lt;h2&gt;A. Milya and Two Arrays&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2059/problem/A&quot;&gt;&lt;strong&gt;A. Milya and Two Arrays&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你两个长度为n的数组a和b，a,b中的每个元素都至少出现两次。你可以重新排列a，最后要使得ai+bi的不同种类大于等于3。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;统计a和b的种类数cnt1,cnt2，因为长度为n且每个种类的数至少出现两次，所以a中每个数贡献的种类数就是出现次数，出现次数，min(
出现次数，cnt2)，只要cnt1∗cnt2&gt;=3就行。赛时没想的很清楚写的cnt1+cnt2&gt;=4，其实一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
  int n;
  std::cin &gt;&gt; n;
  std::set&amp;#x3C;int&gt; a, b;
  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	int x;
  	std::cin &gt;&gt; x;
  	a.insert(x);
  }

  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	int x;
  	std::cin &gt;&gt; x;
  	b.insert(x);
  }

  if (a.size() + b.size() &gt;= 4) {
  	std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
  } else {
  	std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B. Cost of the Array time limit per test1 second&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2059/problem/B&quot;&gt;&lt;strong&gt;B. Cost of the Array time limit per test1 second&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你一个长度为n数组a和一个偶数k。你要把a分成k份。然后把所有偶数份按顺序拼到一起，得到b，求可以得到的bi!=i的最小的i。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们让所有的k−1份都只占一个位置，第二份占多个位置，看能不能不让1开头，如果有我们可以把前面的1都给第一份，那么答案就是1。否则就全部都是1，那么全部给第二个份，那么答案就是2。&lt;br&gt;
注意要特判n==k的情况&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
  int n, k;
  std::cin &gt;&gt; n &gt;&gt; k;
  std::vector&amp;#x3C;int&gt; a(n);
  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	std::cin &gt;&gt; a[i];
  }

  if (n == k) {
  	for (int i = 1, j = 1; i &amp;#x3C; n; i += 2, j ++ ) {
  		if (a[i] != j) {
  			std::cout &amp;#x3C;&amp;#x3C; j &amp;#x3C;&amp;#x3C; endl;
  			return;
  		}
  	}

  	std::cout &amp;#x3C;&amp;#x3C; k / 2 + 1 &amp;#x3C;&amp;#x3C; endl;
  	return;
  } else {
  	for (int i = 1; i &amp;#x3C; n - (k - 2); ++ i) {
  		if (a[i] != 1) {
  			std::cout &amp;#x3C;&amp;#x3C; 1 &amp;#x3C;&amp;#x3C; endl;
  			return;
  		}
  	}

  	std::cout &amp;#x3C;&amp;#x3C; 2 &amp;#x3C;&amp;#x3C; endl;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;C. Customer Service&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2059/problem/C&quot;&gt;&lt;strong&gt;C. Customer Service&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你n个长度为n的数组，你要给每一个数组截断一次，且所有数组截断的位置凑起来正好是一个排列。然后每个数组的值就是截断的后一部分的和。你要让所有数组和的mex最大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;记录每个数组的后缀和与后缀长度相等的位置，那么保留这一段位置可以得到一个数字。于是我们从小到大枚举mex只要有一个没有被操作过的数组可以贡献这个值，就可以继续操作，否则就是答案。然后考虑每个值由哪个数组贡献，应该让可以贡献的最大值最小的数组来贡献这个值。因为其他数组都可以贡献更大的值，应该留下来。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
  int n;
  std::cin &gt;&gt; n;
  std::vector a(n, std::vector&amp;#x3C;int&gt;(n));
  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	for (int j = 0; j &amp;#x3C; n; ++ j) {
  		std::cin &gt;&gt; a[i][j];
  	}
  	a[i].push_back(0);
  	std::reverse(a[i].begin(), a[i].end());
  }

  std::vector&amp;#x3C;std::set&amp;#x3C;std::pair&amp;#x3C;int, int&gt; &gt; &gt; s(n + 1);
  std::vector&amp;#x3C;int&gt; b(n);
  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	i64 t = 0;
  	for (int j = 0; j &amp;#x3C;= n; ++ j) {
  		t += a[i][j];
  		if (j == n || t != j) {
  			b[i] = j;
  			break;
  		}
  	}

  	for (int j = 0; j &amp;#x3C; b[i]; ++ j) {
  		s[j].insert({b[i], i});
  	}
  }

  for (int i = 0; i &amp;#x3C;= n; ++ i) {
  	if (s[i].empty()) {
  		std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; endl;
  		return;
  	}

  	auto [_, x] = *s[i].begin();
  	s[i].erase(s[i].begin());
  	for (int j = 0; j &amp;#x3C; b[x]; ++ j) {
  		s[j].erase({b[x], x});
  	}
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;D. Graph and Graph&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2059/problem/D&quot;&gt;&lt;strong&gt;D. Graph and Graph&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你两个由n个顶点的图，你在图一和图二各有一个起点，你每次要在这两个图上移动，假设从图一移动到了u,
图二移动到了v，移动代价是|u−v|。你要进行无限次操作，求操作的最小代价。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;显然我们让两个图都到一个相同的点u，使得有一个v在图一和图二上都和u有边。那么可以在这两个点上反复横跳，代价是0。否则代价是正无穷。
那么可以考虑最短路，dist[i][j]表示图一在i，图二在j时的最小代价。最后枚举每个i，看有没有一个j使得在两个图上都有边，然后取最小值即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;void solve() {
  int n, s1, s2;
  std::cin &gt;&gt; n &gt;&gt; s1 &gt;&gt; s2;
  -- s1, -- s2;
  std::vector g1(n, std::vector&amp;#x3C;int&gt;(n));
  std::vector g2(n, std::vector&amp;#x3C;int&gt;(n));
  std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt; &gt; adj1(n);
  std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt; &gt; adj2(n);
  int m1, m2;
  std::cin &gt;&gt; m1;
  for (int i = 0; i &amp;#x3C; m1; ++ i) {
  	int u, v;
  	std::cin &gt;&gt; u &gt;&gt; v;
  	-- u, -- v;
  	g1[u][v] = g1[v][u] = 1;
  	adj1[u].push_back(v);
  	adj1[v].push_back(u);
  }

  std::cin &gt;&gt; m2;
  for (int i = 0; i &amp;#x3C; m2; ++ i) {
  	int u, v;
  	std::cin &gt;&gt; u &gt;&gt; v;
  	-- u, -- v;
  	g2[u][v] = g2[v][u] = 1;
  	adj2[u].push_back(v);
  	adj2[v].push_back(u);
  }

  const int inf = 1e9;
  std::vector dist(n, std::vector&amp;#x3C;int&gt;(n, inf));
  std::vector vis(n, std::vector&amp;#x3C;int&gt;(n));
  using A = std::array&amp;#x3C;int, 3&gt;;
  std::priority_queue&amp;#x3C;A, std::vector&amp;#x3C;A&gt;, std::greater&amp;#x3C;A&gt; &gt; heap;
  dist[s1][s2] = 0;
  heap.push({0, s1, s2});
  while (heap.size()) {
  	auto [_, x, y] = heap.top(); heap.pop();
  	if (vis[x][y]) {
  		continue;
  	}

  	for (auto &amp;#x26; i : adj1[x]) {
  		for (auto &amp;#x26; j : adj2[y]) {
  			if (dist[i][j] &gt; dist[x][y] + std::abs(i - j)) {
  				dist[i][j] = dist[x][y] + std::abs(i - j);
  				if (!vis[i][j]) {
  					heap.push({dist[i][j], i, j});
  				}
  			}
  		}
  	}
  }

  int ans = inf;
  for (int i = 0; i &amp;#x3C; n; ++ i) {
  	for (int j = 0; j &amp;#x3C; n; ++ j) {
  	  if (g1[i][j] &amp;#x26;&amp;#x26; g2[i][j]) {
  		  ans = std::min(ans, dist[i][i]);
  		}
  	}
  }

  if (ans == inf) {
  	ans = -1;
  }
  std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/19.BsAWGha7.webp"/><enclosure url="/_astro/19.BsAWGha7.webp"/></item><item><title>将Github pages打包为移动端应用</title><link>https://santisify.top/blog/old/githubpage-to-app</link><guid isPermaLink="true">https://santisify.top/blog/old/githubpage-to-app</guid><pubDate>Sat, 18 Jan 2025 01:28:14 GMT</pubDate><content:encoded>&lt;h2&gt;配置环境&lt;/h2&gt;
&lt;p&gt;首先我们得先配置好环境 
我这里用的是IDEA,也可以用android studio&lt;/p&gt;
&lt;p&gt;首先在IDEA中安装一个叫Android的插件
&lt;img src=&quot;https://s2.loli.net/2025/01/18/YuBtGxPNjUenr6q.png&quot; alt=&quot;image.png&quot;&gt;
下载好后我们需要创建项目
&lt;img src=&quot;https://s2.loli.net/2025/01/18/HjckQeP8LGXhWMi.png&quot; alt=&quot;image.png&quot;&gt;
框选的位置一定要修改(language有误，应该选择kotlin)
&lt;img src=&quot;https://s2.loli.net/2025/01/18/aPnIcXe45WJU8xl.png&quot; alt=&quot;image.png&quot;&gt;
可能会提示下载SDK，直接下载就行了
创建好后，我们需要修改gradle镜像源
&lt;img src=&quot;https://s2.loli.net/2025/01/18/BgOMHLoG7StkyQf.png&quot; alt=&quot;image.png&quot;&gt;
将框选的地址换为&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;https://mirrors.cloud.tencent.com/gradle/gradle-8.2-all.zip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;修改后，重新加载gradle项目即可&lt;/p&gt;
&lt;h2&gt;项目搭建&lt;/h2&gt;
&lt;p&gt;首先我们找到文件&lt;code&gt;app\src\main\java\com\example\myapplication\MainActivity&lt;/code&gt;
若没有修改项目名称，那路径就和我一样的
&lt;img src=&quot;https://s2.loli.net/2025/01/18/jw8aYu3sxOZClW1.png&quot; alt=&quot;image.png&quot;&gt;
将以下代码复制到上面的文件中,项目名称不同下述代码的第一行不用复制，粘贴的时候要保留原有的第一行&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-kotlin&quot;&gt;package com.example.myapplication

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.os.Bundle
import android.util.Log
import android.view.View
import android.webkit.WebResourceRequest
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.RejectedExecutionException
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit


class MainActivity : ComponentActivity() {

    private lateinit var webView: WebView
    private lateinit var swipeRefreshLayout: SwipeRefreshLayout
    private val executor = ThreadPoolExecutor(
        2, // 核心线程数
        4, // 最大线程数
        30L, TimeUnit.SECONDS, // 空闲线程存活时间
        LinkedBlockingQueue(20) // 任务队列容量
    )

    @SuppressLint(&quot;SetJavaScriptEnabled&quot;)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        showWelcomeDialog()

        // 初始化 SwipeRefreshLayout 和 WebView
        swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
        webView = findViewById(R.id.webview)

        // 配置 SwipeRefreshLayout
        swipeRefreshLayout.setOnRefreshListener {
            webView.reload() // 刷新网页
        }

        // 配置 WebView
        val webSettings = webView.settings
        webSettings.javaScriptEnabled = true
        webSettings.domStorageEnabled = true
        webSettings.databaseEnabled = true
        webSettings.setSupportMultipleWindows(true)
        webSettings.cacheMode = WebSettings.LOAD_DEFAULT
        webView.setLayerType(View.LAYER_TYPE_HARDWARE, null) // 启用硬件加速

        // 设置 WebViewClient
        webView.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
                val url = request?.url.toString()
                view?.loadUrl(url)
                return true
            }

            override fun onPageFinished(view: WebView?, url: String?) {
                super.onPageFinished(view, url)
                swipeRefreshLayout.isRefreshing = false // 停止刷新动画
            }
        }

        // 加载你的博客网址
        webView.loadUrl(&quot;https://anzhiyublog.lazy-boy-acmer.cn&quot;)
    }

    @Deprecated(&quot;Deprecated in Java&quot;)
    override fun onBackPressed() {
        if (::webView.isInitialized &amp;#x26;&amp;#x26; webView.canGoBack()) {
            Log.d(&quot;WebView&quot;, &quot;Can go back&quot;)
            webView.goBack()
        } else {
            Log.d(&quot;WebView&quot;, &quot;Not going back&quot;)
            super.onBackPressed()
        }
    }

    // 显示欢迎提示框
    private fun showWelcomeDialog() {
        val builder = AlertDialog.Builder(this)
        builder.setTitle(&quot;\uD83E\uDD74提示&quot;)
        builder.setMessage(&quot;返回键已修复为可返回之前页面\n现无法跳转外部页面&quot;)

        builder.setPositiveButton(&quot;确定&quot;) { dialog, _ -&gt;
            dialog.dismiss()
        }

        val dialog = builder.create()
        dialog.show()
    }

    // 任务入队
    fun enqueueTriggerTask(task: Runnable): Boolean {
        return try {
            executor.execute(task)
            true
        } catch (e: RejectedExecutionException) {
            Log.e(&quot;TaskManager&quot;, &quot;Failed to enqueue task&quot;, e)
            false
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        executor.shutdown()
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开文件 &lt;code&gt;app\src\main\res\layout\activity_main.xml&lt;/code&gt;
&lt;img src=&quot;https://s2.loli.net/2025/01/18/VDlGNUHtMqvuFiO.png&quot; alt=&quot;image.png&quot;&gt;
粘贴以下代码&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;#x3C;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&amp;#x3C;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;&gt;

    &amp;#x3C;androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id=&quot;@+id/swipeRefreshLayout&quot;
            android:layout_width=&quot;match_parent&quot;
            android:layout_height=&quot;match_parent&quot;&gt;

        &amp;#x3C;WebView
                android:id=&quot;@+id/webview&quot;
                android:layout_width=&quot;match_parent&quot;
                android:layout_height=&quot;match_parent&quot;/&gt;
    &amp;#x3C;/androidx.swiperefreshlayout.widget.SwipeRefreshLayout&gt;
&amp;#x3C;/RelativeLayout&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;生成apk&lt;/h2&gt;
&lt;p&gt;点击菜单栏的 &lt;code&gt;Build -&gt; Build Apk(s)&lt;/code&gt;
生成的安装包会在项目根目录下的&lt;strong&gt;app\build\outputs\apk\debug&lt;/strong&gt;里面
至于如何修改Apk的名称和图标，大家可以自行百度或AI&lt;/p&gt;</content:encoded><h:img src="/_astro/logo.Drjc9GyJ.svg"/><enclosure url="/_astro/logo.Drjc9GyJ.svg"/></item><item><title>npm作为图片存储</title><link>https://santisify.top/blog/old/npm-picx</link><guid isPermaLink="true">https://santisify.top/blog/old/npm-picx</guid><pubDate>Wed, 08 Jan 2025 23:19:34 GMT</pubDate><content:encoded>&lt;h2&gt;创建文件夹&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mkdir demo
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;初始化&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;打开编译器创建文件&lt;code&gt;index.js&lt;/code&gt;并填入以下信息&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;function main() {
  console.log(&apos;Hello, world&apos;)
}
main()
export default main
export function Hello(name) {
  console.log(&apos;${ name }}&apos;)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;打开package.json文件&lt;/h2&gt;
&lt;p&gt;现在我们来熟悉下这个文件。&lt;/p&gt;
&lt;p&gt;| 字段           | 备注                                          |
| -------------- | --------------------------------------------- |
| name           | npm包的名称，也就是publish后的名称            |
| version        | 每次publish的时候记得修改这个，必须要是新版本 |
| desdescription | 对这个npm包的描述                             |
| main           | 链接到这个包后，默认打开的文件                |
| keywords       | 关键词。若是自行使用，可以不配置              |
| author         | 作者。填写自己的用户名就行                    |&lt;/p&gt;
&lt;p&gt;现在在&lt;strong&gt;json&lt;/strong&gt;文件中添加以下信息&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;files&quot;: [&quot;index.js&quot;, &quot;&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;[]&lt;/code&gt;中添加需要发布的文件或文件夹，多个文件或文件夹用&lt;code&gt;,&lt;/code&gt;隔开并且每个都用&lt;code&gt;&quot;&quot;&lt;/code&gt;包裹。
自行检查语法错误&lt;/p&gt;
&lt;h2&gt;发布&lt;/h2&gt;
&lt;p&gt;由于镜像源问题，我们可能会发布失败
我们直接在&lt;strong&gt;cmd&lt;/strong&gt;中切换镜像源&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm config set registry https://registry.npmjs.org
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;切换后发布&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm publish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;发布成功后我们再将镜像源切换回&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm config set registry https://registry.npmmirror.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若不切换，可能会出现 &lt;code&gt;npm install&lt;/code&gt; 失败&lt;/p&gt;
&lt;h2&gt;访问文件&lt;/h2&gt;
&lt;p&gt;访问npm包的文件我们可以使用&lt;a href=&quot;https://www.unpkg.com&quot;&gt;unpkg&lt;/a&gt;来访问
以下链接是访问最新发布的npm包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://unpkg.com/npm包名/file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;若在包名后添加&lt;code&gt;@版本号&lt;/code&gt;，则可以访问指定版本的npm包&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# 准确版本号
https://unpkg.com/npm包名@1.1.1/file
# 模糊版本号(访问的是这个大版本的最新的版本号)
https://unpkg.com/npm包名@1/file
# 模糊版本号(访问的是这个小版本的最新的版本号)
https://unpkg.com/npm包名@1.1/file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了，今天的分享就到这里了，拜拜！&lt;/p&gt;</content:encoded><h:img src="/_astro/npm-logo.CDm2UwD9.jpg"/><enclosure url="/_astro/npm-logo.CDm2UwD9.jpg"/></item><item><title>StarRail-忘归人</title><link>https://santisify.top/blog/old/starrail-fugue</link><guid isPermaLink="true">https://santisify.top/blog/old/starrail-fugue</guid><pubDate>Tue, 24 Dec 2024 11:38:04 GMT</pubDate><content:encoded/><h:img src="/_astro/15.BDPZk01-.webp"/><enclosure url="/_astro/15.BDPZk01-.webp"/></item><item><title>Codeforces Round 991 (Div.3)</title><link>https://santisify.top/blog/old/cf2050</link><guid isPermaLink="true">https://santisify.top/blog/old/cf2050</guid><description>codeforces-round-991(A-D)</description><pubDate>Fri, 06 Dec 2024 10:25:16 GMT</pubDate><content:encoded>&lt;p&gt;{% note blue &apos;fas fa-bullhorn&apos; simple %}打过的最难的div3{% endnote %}&lt;/p&gt;
&lt;h2&gt;A.Line Breaks&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2050/problem/A&quot;&gt;Line Breaks&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs A %}&lt;/p&gt;
&lt;p&gt;Kostya has a text s consisting of n words made up of Latin alphabet letters. He also has two strips on which he must write the text. The first strip can hold m characters, while the second can hold as many as needed.&lt;/p&gt;
&lt;p&gt;Kostya must choose a number x and write the first x words from s on the first strip, while all the remaining words are written on the second strip. To save space, the words are written without gaps, but each word must be entirely on one strip.&lt;/p&gt;
&lt;p&gt;Since space on the second strip is very valuable, Kostya asks you to choose the maximum possible number x such that all words s1,s2,…,sx fit on the first strip of length m.&lt;/p&gt;
&lt;p&gt;一段文本有 $n$ 个单词，现将这段文本写在纸上，单词间无间隔，在第一页纸能写 $m$ 个字符，但是一个单词必须出现在同一页纸上。
问：第一页纸能写多少个单词&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;模拟&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

using i128 = __int128;
using i64 = long long;
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const i64 inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;
std::mt19937_64 rng(std::chrono::system_clock::now().time_since_epoch().count());

void solve() {
	int n, m, f = 1;
	std::cin &gt;&gt; n &gt;&gt; m;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; s[i];
	}

	int su = 0, ct = 0;
	for(int i = 0; i &amp;#x3C; n; i++) {
		if (su + s[i].size() &amp;#x3C;= m) {
			ct++;
			su += (int) s[i].size();
		} else {
			break;
		}
	}
	std::cout &amp;#x3C;&amp;#x3C; ct &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Transfusion&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2050/problem/B&quot;&gt;Transfusion&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs B %}&lt;/p&gt;
&lt;p&gt;You are given an array a of length n. In one operation, you can pick an index i from 2 to n−1 inclusive, and do one of the following actions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Decrease $a_{i-1}$ by 1, then increase $a_{i+1}$ by 1.&lt;/li&gt;
&lt;li&gt;Decrease $a_{i+1}$ by 1, then increase $a_{i-1}$ by 1.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After each operation, all the values must be non-negative. Can you make all the elements equal after any number of operations?&lt;/p&gt;
&lt;p&gt;给定长度为 $n$ 的数组可以执行以下操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$a_{i-1}=a_{i-1}-1,a_{i+1}=a_{i+1}+1$;&lt;/li&gt;
&lt;li&gt;$a_{i-1}=a_{i-1}+1,a_{i+1}=a_{i+1}-1$;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;问：是否可以通过以上操作将数组的所有元素变为相等。&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;可以发现每次修改的下标奇偶性相同，我们可以分别记录下奇数下标和偶数下标的 $sum$ 和 $ct$。
那么能实现的判断条件也很简单，如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\frac{sum_{奇}}{ct_{奇}} = \frac {sum_{偶}}{ct_{偶}}$&lt;/li&gt;
&lt;li&gt;$\frac{sum_{奇}}{ct_{奇}}=0 ，\frac{sum_{偶}}{ct_{偶}} =0$&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int, int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
  int n;
  std::cin &gt;&gt; n;
  std::vector&amp;#x3C;int&gt; a(n);
  int ct[2]{}, sum[2]{};
  int s = 0;
  for (int i = 0; i &amp;#x3C; n; i++) {
    std::cin &gt;&gt; a[i];
    sum[i % 2] += a[i];
    ct[i % 2] ++;
  }

  if(sum[0] % ct[0] || sum[1] % ct[1] || sum[0] / ct[0] != sum[1] / ct[1]) {
    std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
  }else {
    std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
  }
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  int Lazy_boy_ = 1;
  std::cin &gt;&gt; Lazy_boy_;
  while (Lazy_boy_--) solve();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Uninteresting Number&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2050/problem/C&quot;&gt;Uninteresting Number&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs C %}&lt;/p&gt;
&lt;p&gt;You are given a number n with a length of no more than 105.&lt;/p&gt;
&lt;p&gt;You can perform the following operation any number of times: choose one of its digits, square it, and replace the original digit with the result. The result must be a digit (that is, if you choose the digit x, then the value of x2 must be less than 10).&lt;/p&gt;
&lt;p&gt;Is it possible to obtain a number that is divisible by 9 through these operations?&lt;/p&gt;
&lt;p&gt;给你一个长度不超过 $10^5$ 的数字 $n$ 。&lt;/p&gt;
&lt;p&gt;你可以多次进行下面的运算：选择其中一个数字，将其平方，然后用运算结果替换原来的数字。结果必须是一位数字(也就是说，如果您选择数字 $x$ ，那么 $x^2$ 的值必须小于 $10$ )。&lt;/p&gt;
&lt;p&gt;通过这些运算，有可能得到一个能被 $9$ 整除的数吗？&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;数字必须是数字这一要求对变换有如下限制：我们可以将 $0$ 变换为 $0$ ，将 $1$ 变换为 $1$ ，将 $2$ 变换为 $4$ ，将 $3$ 变换为 $9$ 。任何其他数字的平方都会超过 9，因此无法变换。涉及 $0$ 和 $1$ 的变换都是无用的，因此我们有两种可能的操作：将数字 $2$ 或数字 $3$ 平方。&lt;/p&gt;
&lt;p&gt;我们将使用 $9$ 的可除规则。它规定，当且仅当一个数字的数位之和能被 $9$ 整除时，这个数字才能被 $9$ 整除。让我们看看数字的位数之和在可能的变换中会发生怎样的变化。如果我们对 $2$ 进行平方运算，数位之和将增加 $2^2 - 2 = 2$ ；如果我们对 $3$ 进行平方运算，数位之和将增加 $3^2 - 3 = 6$ 。&lt;/p&gt;
&lt;p&gt;我们将计算数字中 $2$ 的位数和数字中 $3$ 的位数。我们可以从可用的数位 $2$ 和 $3$ 中选择转换的个数。变换超过 8 个 2 和超过 8 个 3 的余数是没有意义的，因为它们的变换加到总和中的余数模 $9$ 会重复。&lt;/p&gt;
&lt;p&gt;因此，最终的解法是这样的：我们计算数字的位数之和，数出 $2$ 和 $3$ 的位数。我们将遍历改变 $2$ 的位数（可能为 0，但不超过 8 位），以及改变 $3$ 的位数（可能为 0，但也不超过 8 位）。假设我们改变了 $x$ 位数 $2$ 和 $y$ 位数 $3$ ，那么这个数的位数总和就增加了 $x * 2 + y * 6$ 。如果新的和能被 $9$ 整除，那么答案就是 &quot;是&quot;。如果在迭代过程中从未出现过这种情况，则答案为 &quot;否&quot;。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int, int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
  std::string s;
  std::cin &gt;&gt; s;
  int sum = 0, ct1 = 0, ct2 = 0;
  for (auto i : s) {
    sum += i - &apos;0&apos;;
    ct1 += (i == &apos;2&apos; ? 1 : 0);
    ct2 += (i == &apos;3&apos; ? 1 : 0);
  }

  for (int i = 0; i &amp;#x3C;= std::min(9ll, ct1); i++) {
    for (int j = 0; j &amp;#x3C;= std::min(9ll, ct2); j++) {
      if ((sum + i * 2 + j * 6) % 9 == 0) {
        std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
        return;
      }
    }
  }

  std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  int Lazy_boy_ = 1;
  std::cin &gt;&gt; Lazy_boy_;
  while (Lazy_boy_--) solve();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Digital string maximization&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2050/problem/D&quot;&gt;Digital string maximization&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs D %}&lt;/p&gt;
&lt;p&gt;You are given a string s, consisting of digits from 0 to 9. In one operation, you can pick any digit in this string, except for 0 or the leftmost digit, decrease it by 1, and then swap it with the digit left to the picked.&lt;/p&gt;
&lt;p&gt;For example, in one operation from the string 1023, you can get 1103 or 1022.&lt;/p&gt;
&lt;p&gt;Find the lexicographically maximum string you can obtain after any number of operations.&lt;/p&gt;
&lt;p&gt;给你一个由 0 到 9 的数字组成的字符串 s。在一次操作中，您可以选取该字符串中除 0 或最左边数字之外的任意一个数字，将其减少 1，然后将其与左边的数字对调。&lt;/p&gt;
&lt;p&gt;例如，从字符串 1023 中进行一次运算，可以得到 1103 或 1022。&lt;/p&gt;
&lt;p&gt;找出任意多次运算后可以得到的词性最大的字符串。&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;p&gt;让我们看看数字 $s_i$ 。我们可以看到，我们不能将它向左移动超过 $s_i$ 次，因为它之后将是 $0$ 。因此，我们可以说，只有从 $i$ 到 $i+9$ 的指数上的数字才能位于指数 $i$ 上，因为最大的数字 $9$ 向左移动的次数不超过 $9$ 。&lt;/p&gt;
&lt;p&gt;因此，我们可以对每个 $i$ 从 $s_i$ 到 $s_{i+9}$ 的所有数字进行暴力推理，选出 $j$ 中 $s_j - (j - i)$ 最大的数字；如果有多个最大选项，我们将最小化 $j$ 。之后，我们将 $s_j$ 向左移动，直到它位于索引 $i$ 上。&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int, int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
  std::string s;
  std::cin &gt;&gt; s;
  for (int i = 0; i &amp;#x3C; s.size(); i++) {
    int x = s[i] - &apos;0&apos;, pos = i;
    for (int j = i; j &amp;#x3C; std::min(i + 10, (int)s.size()); j++) {
      if (s[j] - &apos;0&apos; - (j - i) &gt; x) {
        x = s[j] - &apos;0&apos; - (j - i);
        pos = j;
      }
    }
    while (pos &gt; i) {
      std::swap(s[pos], s[pos - 1]);
      pos--;
    }
    s[i] = x + &apos;0&apos;;
  }
  std::cout &amp;#x3C;&amp;#x3C; s &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
  int Lazy_boy_ = 1;
  std::cin &gt;&gt; Lazy_boy_;
  while (Lazy_boy_--) solve();
  return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/3.BbkNsNA-.webp"/><enclosure url="/_astro/3.BbkNsNA-.webp"/></item><item><title>Atcoder beginner contest 378</title><link>https://santisify.top/blog/old/abc378</link><guid isPermaLink="true">https://santisify.top/blog/old/abc378</guid><description>Atcoder abc 378 (A-D)</description><pubDate>Fri, 22 Nov 2024 13:38:05 GMT</pubDate><content:encoded>&lt;h2&gt;A.Pairing&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc378/tasks/abc378_a&quot;&gt;Pairing&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs A %}&lt;/p&gt;
&lt;p&gt;There are four balls, and the color of the $i$-th ball is $A_i$.
Find the maximum number of times you can perform this operation: choose two balls of the same color and discard both.&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::map&amp;#x3C;int, int&gt; mp;
	for(int i = 0; i &amp;#x3C; 4; i++) {
		int x;
		std::cin &gt;&gt; x;
		mp[x]++;
	}

	int s = 0;
	for(auto [x, y] : mp) {
		s += y / 2;
	}
	std::cout &amp;#x3C;&amp;#x3C; s &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Garbage Collection&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc378/tasks/abc378_b&quot;&gt;Garbage Collection&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs B %}&lt;/p&gt;
&lt;p&gt;In AtCoder City, $N$ types of garbage are collected regularly. The $i$-th type of garbage $(i=1,2,\dots,N)$ is collected on days when the date modulo $q_i$ equals $r_i$.
Answer $Q$ queries. In the $j$-th query $(j=1,2,\dots,Q)$, given that the $t_j$-th type of garbage is put out on day $d_j$, answer the next day on which it will be collected.
Here, if the $i$-th type of garbage is put out on a day when that type of garbage is collected, then the garbage will be collected on the same day.&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;模拟&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;pii &gt; a(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		int u, v;
		std::cin &gt;&gt; u &gt;&gt; v;
		a[i] = {u, v};
	}

	int q;
	std::cin &gt;&gt; q;
	while (q--) {
		int t, d;
		std::cin &gt;&gt; t &gt;&gt; d;
		t--;
		auto [x, y] = a[t];
		int w = d / x * x + y;
		if (w &amp;#x3C; d) w += x;
		std::cout &amp;#x3C;&amp;#x3C; w &amp;#x3C;&amp;#x3C; endl;
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Repeating&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc378/tasks/abc378_c&quot;&gt;Repeating&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs C %}&lt;/p&gt;
&lt;p&gt;You are given a sequence of $N$ positive numbers, $A = (A_1, A_2, \dots, A_N)$. Find the sequence $B = (B_1, B_2, \dots, B_N)$ of length $N$ defined as follows.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For $i = 1, 2, \dots, N$, define $B_i$ as follows: - Let $B_i$ be the most recent position before $i$ where an element equal to $A_i$ appeared. If such a position does not exist, let $B_i = -1$.&lt;br&gt;
More precisely, if there exists a positive integer $j$ such that $A_i = A_j$ and $j &amp;#x3C; i$, let $B_i$ be the largest such $j$. If no such $j$ exists, let $B_i = -1$.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;给你一个由 $N$ 个正数 $A = (A_1, A_2, \dots, A_N)$ 组成的数列。求长度为 $N$ 的序列 $B = (B_1, B_2, \dots, B_N)$ 的定义如下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对于 $i = 1, 2, \dots, N$ ，定义 $B_i$ 如下：- 设 $B_i$ 是在 $i$ 之前出现过与 $A_i$ 相同元素的最近位置。如果不存在这样的位置，则设为 $B_i = -1$ 。&lt;br&gt;
更确切地说，如果存在一个正整数 $j$ ，使得 $A_i = A_j$ 和 $j &amp;#x3C; i$ ，那么就让 $B_i$ 成为最大的 $j$ 。如果不存在这样的 $j$ , 则设 $B_i = -1$ .
{% endtabs %}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;标记之前出现过的数的位置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; a(n + 2), b(n + 2);
	std::map&amp;#x3C;int, int&gt; mp;
	for(int i = 1; i &amp;#x3C;= n; i++) std::cin &gt;&gt; a[i];
	b[1] = -1;
	mp[a[1]] = 1;
	for(int i = 2; i &amp;#x3C;= n; i++) {
		if (mp.find(a[i]) != mp.end()) {
			b[i] = mp[a[i]];
		}else {
			b[i] = -1;
		}
		mp[a[i]] = i;
	}

	for(int i = 1; i &amp;#x3C;= n; i++) std::cout &amp;#x3C;&amp;#x3C; b[i] &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n];
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Count Simple Paths&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc378/tasks/abc378_d&quot;&gt;Count Simple Paths&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs D %}&lt;/p&gt;
&lt;p&gt;There is a grid of $H \times W$ cells. Let $(i, j)$ denote the cell at the $i$-th row from the top and the $j$-th column from the left.
Cell $(i, j)$ is empty if $S_{i,j}$ is &lt;code&gt;.&lt;/code&gt;, and blocked if it is &lt;code&gt;#&lt;/code&gt;.
Count the number of ways to start from an empty cell and make $K$ moves to adjacent cells (up, down, left, or right), without passing through blocked squares and not visiting the same cell more than once.
Specifically, count the number of sequences of length $K+1$, $((i_0, j_0), (i_1, j_1), \dots, (i_K, j_K))$, satisfying the following.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1 \leq i_k \leq H$, $1 \leq j_k \leq W$, and $S_{i_k, j_k}$ is &lt;code&gt;.&lt;/code&gt;, for each $0 \leq k \leq K$.&lt;/li&gt;
&lt;li&gt;$|i_{k+1} - i_k| + |j_{k+1} - j_k| = 1$ for each $0 \leq k \leq K-1$.&lt;/li&gt;
&lt;li&gt;$(i_k, j_k) \neq (i_l, j_l)$ for each $0 \leq k &amp;#x3C; l \leq K$.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有一个由 $H \times W$ 个单元格组成的网格。让 $(i, j)$ 表示从上往下第 $i$ 行，从左往上第 $j$ 列的单元格。
如果 $S_{i,j}$ 是 &lt;code&gt;.&lt;/code&gt;，则单元格 $(i, j)$ 为空；如果是 &lt;code&gt;#&lt;/code&gt; ，则单元格 $(i, j)$ 阻塞。
计算从一个空单元格开始，向相邻单元格（向上、向下、向左或向右）进行 $K$ 移动，而不经过被阻塞的方格，并且不多次访问同一单元格的方法的数目。
具体地说，计算满足以下条件的长度为 $K+1$ , $((i_0, j_0), (i_1, j_1), \dots, (i_K, j_K))$ 的序列的个数。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1 \leq i_k \leq H$ 、 $1 \leq j_k \leq W$ 和 $S_{i_k, j_k}$ 为 &lt;code&gt;.&lt;/code&gt;，每个 $0 \leq k \leq K$ 为 &lt;code&gt;.&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;$|i_{k+1} - i_k| + |j_{k+1} - j_k| = 1$ 为每个 $0 \leq k \leq K-1$ 。&lt;/li&gt;
&lt;li&gt;每个 $0 \leq k &amp;#x3C; l \leq K$ 的 $(i_k, j_k) \neq (i_l, j_l)$ 。
{% endtabs %}&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;dfs暴搜&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

void solve() {
	int n, m, k;
	std::cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for(int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; s[i];

	auto check = [&amp;#x26;](int x, int y) {
		return x &gt;= 0 &amp;#x26;&amp;#x26; x &amp;#x3C; n &amp;#x26;&amp;#x26; y &gt;= 0 &amp;#x26;&amp;#x26; y &amp;#x3C; m;
	};

	int res = 0;

	std::vector vis(n, std::vector&amp;#x3C;bool&gt;(m, false));
	std::function&amp;#x3C;void(int, int, int)&gt; dfs = ([&amp;#x26;](int x, int y, int val) {
		vis[x][y] = true;
		if (val == k) {
			res++;
			return;
		}
		for(int i = 0; i &amp;#x3C; 4; i++) {
			int u = x + dx[i], v = y + dy[i];
			if (check(u, v) &amp;#x26;&amp;#x26; !vis[u][v] &amp;#x26;&amp;#x26; s[u][v] == &apos;.&apos;) {
				dfs(u, v, val + 1);
				vis[u][v] = false;
			}
		}
	});

	for(int i = 0; i &amp;#x3C; n; i++) {
		for(int j = 0; j &amp;#x3C; m; j++) {
			if (s[i][j] == &apos;.&apos;)
				dfs(i, j, 0), vis[i][j] = false;
		}
	}
	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/10.WxjKbdnc.webp"/><enclosure url="/_astro/10.WxjKbdnc.webp"/></item><item><title>Atcoder beginner contest 376</title><link>https://santisify.top/blog/old/abc376</link><guid isPermaLink="true">https://santisify.top/blog/old/abc376</guid><description>Atcoder abc 376 (A-E)</description><pubDate>Thu, 24 Oct 2024 09:59:57 GMT</pubDate><content:encoded>&lt;h2&gt;A.Candy Button&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc376/tasks/abc376_a&quot;&gt;Candy Button&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;一个按钮，按了会发糖。&lt;/p&gt;
&lt;p&gt;给定多次按的时间。如果这次按的时间距离上次发糖时间超过了$c$，则发个糖。问发的糖数量。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;发糖的前提是距离上次发糖时间大于等于$c$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;
#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
    int n, k, ct = 0;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n);
    for(int i = 0 ; i &amp;#x3C;n ; i ++) {
        std::cin &gt;&gt; a[i];
    }
    ct = 1;
    int pos = 0;
    for(int i = 1; i &amp;#x3C; n; i ++) {
        if(a[i] - a[pos] &gt;= k) {
            ct ++;
            pos = i;
        }
    }

    std::cout &amp;#x3C;&amp;#x3C; ct &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Hands on Ring (Easy)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc376/tasks/abc376_b&quot;&gt;Hands on Ring (Easy)&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;$n$的环形格子。两个棋子，初始位于$0$, $1$。
给定 $q$个指令，每个指令指定一个棋子移动到某个格子上，期间不能移动另外一个棋子。
依次执行这些指令，问移动的次数。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;简单模拟一下即可，可能我的代码有点“屎山”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;
#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
    int n, q;
    std::cin &gt;&gt; n &gt;&gt; q;
    int res = 0;
    int l = 1, r = 2;
    while(q --) {
        char c;
        int x;
        std::cin &gt;&gt; c &gt;&gt; x;
        if(c == &apos;L&apos; &amp;#x26;&amp;#x26; x != l) {
            if(l &amp;#x3C; r) {
                if(x &amp;#x3C;= r) {
                    res += abs(x - l);
                }else {
                    res += (l + n - x);
                }
            }else {
                if(x &gt;= r) {
                    res += abs(x - l);
                }else {
                    res += (x + n - l);
                }
            }
            l = x;
        }else if(c == &apos;R&apos; &amp;#x26;&amp;#x26; x != r){
            if(l &amp;#x3C; r) {
                if(x &gt;= l) {
                    res += abs(r - x);
                }else {
                    res += (n - r + x);
                }
            }else {
                if(x &amp;#x3C;= l) {
                    res += abs(r - x);
                }else {
                    res += (r + n - x);
                }
            }
            r = x;
        }
    }

    std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}


signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Prepare Another Box&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc376/tasks/abc376_c&quot;&gt;Prepare Another Box&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定 $n$个球的大小和$n - 1$个箱子的大小。现买一箱子，要求尺寸最小，使得 $n$个球恰好可以放进 $n$个箱子里,一个箱子有且只能放一个球。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;要求找出箱子大小的最小值，那么我们可以先排个序，若最后一个箱子越大，可以放入的方法就越多，反之越少。那么我们怎么求找到这个值呢？我们只需要一个箱子我们可以去尝试每一个大小箱子，但是这不现实，于是就可以想到二分，可以大大减小时间复杂度，二分条件便是查看是否有球无法放入箱子。二分完成后，要检查二分后的答案是否满足题意。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;
#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n), b(n - 1);
    for(int i = 0; i &amp;#x3C; n; i ++) {
        std::cin &gt;&gt; a[i];
    }

    for(int i = 0; i &amp;#x3C; n - 1; i ++) {
        std::cin &gt;&gt; b[i];
    }

    std::sort(a.begin(), a.end());
    std::sort(b.begin(), b.end());
    std::function&amp;#x3C;bool(int)&gt; check = ([&amp;#x26;](int x) -&gt; bool {
        auto t = b;
        t.push_back(x);
        std::sort(t.begin(), t.end());
        for(int i = 0 ; i &amp;#x3C; n ; i ++) {
            if(a[i] &gt; t[i]) return false;
        }
        return true;
    });

    int l = 1, r = inf;
    while(l &amp;#x3C; r) {
        int mid = (l + r) &gt;&gt; 1;
        if(check(mid)) {
            r = mid;
        }else {
            l = mid + 1;
        }
    }
    if(l == inf) {
        std::cout &amp;#x3C;&amp;#x3C; -1 &amp;#x3C;&amp;#x3C; endl;
    }else{
        std::cout &amp;#x3C;&amp;#x3C; l &amp;#x3C;&amp;#x3C; endl;
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Cycle&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc376/tasks/abc376_d&quot;&gt;Cycle&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定一张有向图，问包含点$1$的环的最小环点数。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;要确保点数最小,且有回路，那么只有 $BFS$,从点 $1BFS$，每次到达点$1$时更新答案。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, m;
	std::cin &gt;&gt; n &gt;&gt; m;
	std::vector a(n + 1, std::vector&amp;#x3C;int&gt;());

	for(int i = 0; i &amp;#x3C; m; i++) {
		int u, v;
		std::cin &gt;&gt; u &gt;&gt; v;
		a[u].push_back(v);
	}

	std::vector&amp;#x3C;int&gt; dis(n + 1, -1ll);
	std::queue&amp;#x3C;int&gt; q;
	dis[1] = 0;
	q.push(1);
    int res = inf;
	while (q.size()) {
		auto t = q.front();
		q.pop();
		for(auto i : a[t]) {
			if(i == 1) {
				res = std::min(res, dis[t] + 1);
			}
			if(dis[i] == -1) {
				dis[i] = dis[t] + 1;
				q.push(i);
			}
		}
	}
	if(res &gt; n) {
		std::cout &amp;#x3C;&amp;#x3C; -1 &amp;#x3C;&amp;#x3C; endl;
	}else {
		std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	// std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;E.Max × Sum&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc376/tasks/abc376_e&quot;&gt;Max × Sum&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定$n$, $k$和两数组 $A$,$B$，$S$是大小为 $k$ 的 ${1,2,…,N}$ 的子集,求 $\max_{i \in S} A_{i} * \sum_{i \in S}B_{i}$ 的最小值。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;枚举$A_{i}$，剩下的问题就是找满足 $A_{j} \le A_{i}$的前$k-1$小的$B_{j}$的和。首先对数组 $A$进行排序，并且数组$B$与数组$A$一同变化（可以用pair）。然后依次枚举 $A_{i}$，此即为$\max_{i \in S} A_{i}$。然后找$1 \le j \le i$中最小的$k - 1$个$B_{i}$。考虑如何维护前 $k-1$小的和，因为会有不断的$B_{i}$加入，会不断淘汰较大的$B_{i}$，因此可以用优先队列维护这些 $B_{i}$在优先队列不断 &lt;code&gt;push&lt;/code&gt;,&lt;code&gt;pop&lt;/code&gt;时维护其里面的值的和即可。其时间复杂度为$O(n \log n)$注意枚举$A_{i}$时， $B_{i}$是一定要选的，因此要从优先队列里求出前$k - 1$小的和（但第$k$小的不能丢弃，它可能比$B_{i}$小，只是因为此时 $B_{i}$必选，因而暂时不能选它）。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, k;
	std::cin &gt;&gt; n &gt;&gt; k;

	std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt; &gt; a(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i].first;
	}

	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i].second;
	}


	std::sort(a.begin(), a.end(), [&amp;#x26;](pii aa, pii bb) {
		return aa.first &amp;#x3C; bb.first;
	});

	int s = 0;
	std::priority_queue&amp;#x3C;int, std::vector&amp;#x3C;int&gt;, std::less&amp;#x3C;&gt; &gt; pq;
	for(int i = 0; i &amp;#x3C; k; i++) {
		pq.push(a[i].second);
		s += a[i].second;
    }

    int res = s * a[k - 1].first;
	for(int i = k; i &amp;#x3C; n; i++) {
		auto [x, y] = a[i];

		if (y &amp;#x3C; pq.top()) {
			s -= pq.top();
			pq.pop();
			pq.push(y);
			s += y;
		}

		res = std::min(res, s * x);
	}

	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/8.p_lru1H2.webp"/><enclosure url="/_astro/8.p_lru1H2.webp"/></item><item><title>Atcoder beginner contest 377</title><link>https://santisify.top/blog/old/abc377</link><guid isPermaLink="true">https://santisify.top/blog/old/abc377</guid><description>Atcoder abc 377 (A-E)</description><pubDate>Thu, 24 Oct 2024 09:59:57 GMT</pubDate><content:encoded>&lt;h2&gt;A.Rearranging ABC&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc377/tasks/abc377_a&quot;&gt;Rearranging ABC&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定字符串$s$,判断是否可以组成 $ABC$&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;排个序就行了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::string s;
	std::cin &gt;&gt; s;
	std::sort(s.begin(), s.end());
	std::cout &amp;#x3C;&amp;#x3C; (s == &quot;ABC&quot; ? &quot;Yes&quot; : &quot;No&quot;) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Avoid Rook Attack&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc377/tasks/abc377_b&quot;&gt;Avoid Rook Attack&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给出棋盘，其中放有的位置为 &lt;code&gt;#&lt;/code&gt;, 在放有棋子的上下左右四个方向不能放棋子，问有多少个位置可以放棋子.&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;模拟下即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::vector&amp;#x3C;std::string&gt; s(8, &quot;&quot;);
	for(int i = 0; i &amp;#x3C; 8; i++) {
		std::cin &gt;&gt; s[i];
	}

	std::vector a(8, std::vector&amp;#x3C;int&gt;(8, 1));
	for(int i = 0; i &amp;#x3C; 8; i++) {
		for(int j = 0; j &amp;#x3C; 8; j++) {
			if (s[i][j] == &apos;#&apos;) {
				for(int l = 0; l &amp;#x3C; 8; l++) {
					a[i][l] = 0;
				}

				for(int l = 0; l &amp;#x3C; 8; l++) {
					a[l][j] = 0;
				}
			}
		}
	}
	int res = 0;
	for(auto i : a) {
		for(auto j : i) {
			res += j;
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Avoid Knight Attack&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc377/tasks/abc377_c&quot;&gt;Avoid Knight Attack&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://img.atcoder.jp/abc377/871985d4de26cef302c00cdd6f178880.png&quot; alt=&quot;&quot;&gt;
给定$n * n$ 的棋盘和 $m$个棋子位置,其中棋子能走的位置上图所示,问多少个位置可以放棋子,并且不被吃掉&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;模拟，需要注意边界处理&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, m;
	std::cin &gt;&gt; n &gt;&gt; m;

	int dx[] = {-2, -2, -1, -1, 1, 1, 2, 2},
			dy[] = {-1, 1, -2, 2, -2, 2, -1, 1};

	auto check = [&amp;#x26;](int x, int y) {
		return 0 &amp;#x3C; x &amp;#x26;&amp;#x26; x &amp;#x3C;= n &amp;#x26;&amp;#x26; 0 &amp;#x3C; y &amp;#x26;&amp;#x26; y &amp;#x3C;= n;
	};
	std::set&amp;#x3C;pii &gt; se;
	for(int i = 0; i &amp;#x3C; m; i++) {
		int x, y;
		std::cin &gt;&gt; x &gt;&gt; y;
		se.insert({x, y});
		for(int j = 0; j &amp;#x3C; 8; j++) {
			int u = x + dx[j], v = y + dy[j];
			if (check(u, v)) se.insert({u, v});
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; n * n - se.size() &amp;#x3C;&amp;#x3C; endl;

}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Many Segments 2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc377/tasks/abc377_d&quot;&gt;Many Segments 2&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给你两个长度分别为 $N$ 、 $L=(L_1,L_2,\ldots,L_N)$ 和 $R=(R_1,R_2,\ldots,R_N)$ 的正整数序列，以及一个整数 $M$ 。
求满足以下两个条件的整数对 $(l,r)$ 的个数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1\le l \le r \le M$&lt;/li&gt;
&lt;li&gt;对于每一个 $1\le i\le N$ ，区间 $[l,r]$ 并不完全包含区间 $[L_i,R_i]$ 。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;考虑 $O(m)$的同时，维护一个左边界，就是当前位置能最多往前多少是刚好不完全覆盖的，最后这个左边界需要取个 &lt;code&gt;max&lt;/code&gt; ，因为如果前面的左边界更右，那后面的左边界也要和前面一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, m;
	std::cin &gt;&gt; n &gt;&gt; m;

	std::vector&amp;#x3C;int&gt; a(n + m, 1);
	for(int i = 0, l, r; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; l &gt;&gt; r;
		a[r] = std::max(a[r], l + 1);
	}

	for(int i = 1; i &amp;#x3C;= m; i++) {
		a[i] = std::max(a[i], a[i - 1]);
	}

	int res = 0;
	for(int i = 1; i &amp;#x3C;= m; i++) {
		res += i - a[i] + 1;
	}

	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;E.Permute K times 2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc377/tasks/abc377_e&quot;&gt; Permute K times 2&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定长度为 $N$的数组 $P$,将 $P_{i}$替换为 $P_{P_{i}}$操作 $K$次,输出 $K$次操作后的数组.&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;在替换时，某个数多替换几轮就可能回到替换前的位置，那么我们就只需要找出环的大小即可，随后再取模即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, k;
	std::cin &gt;&gt; n &gt;&gt; k;
	std::vector&amp;#x3C;int&gt; P(n);

	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; P[i], P[i]--;
	}

	auto qpow = [&amp;#x26;](int a, int b, int p) {
		int res = 1;
		while (b) {
			if (b &amp;#x26; 1) res = res * a % p;
			a = a * a % p;
			b &gt;&gt;= 1;
		}
		return res;
	};

	std::vector&amp;#x3C;bool&gt; vis(n, false);
	for(int i = 0; i &amp;#x3C; n; i++) {
		if (vis[i]) continue;
		int j = i;
		std::vector&amp;#x3C;int&gt; t;
		while (!vis[j]) {
			vis[j] = true, t.push_back(j);
			j = P[j];
		}

		int w = qpow(2, k, t.size());
		for(int x = 0; x &amp;#x3C; t.size(); x++) {
			P[t[x]] = t[(x + w) % t.size()];
		}
	}

	for(int i = 0; i &amp;#x3C; n; i++) std::cout &amp;#x3C;&amp;#x3C; P[i] + 1 &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n - 1];
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/9.BbNoAMaV.webp"/><enclosure url="/_astro/9.BbNoAMaV.webp"/></item><item><title>Atcoder beginner contest 374</title><link>https://santisify.top/blog/old/abc374</link><guid isPermaLink="true">https://santisify.top/blog/old/abc374</guid><description>Atcoder abc 374(A-D)</description><pubDate>Mon, 07 Oct 2024 14:07:03 GMT</pubDate><content:encoded>&lt;h2&gt;A.Takahashi san 2&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc374/tasks/abc374_a&quot;&gt;Takahashi san 2&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;判断字符串末尾是否有 &lt;code&gt;san&lt;/code&gt; 这个后缀&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::string s;
	std::cin &gt;&gt; s;
	std::string t = s.substr(s.size() - 3);
	std::cout &amp;#x3C;&amp;#x3C; (t == &quot;san&quot; ? &quot;Yes&quot; : &quot;No&quot;) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Unvarnished Report&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc374/tasks/abc374_b&quot;&gt;Unvarnished Report&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定字符串 $S$ 和 $T$,若字符串 $S$ 和字符串 $T$ 完全相等,则输出 $0$ 否则输出 $S$ 和 $T$ 第一个不相同的位置.&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;首先判断两个字符串是否相同,&lt;/p&gt;
&lt;p&gt;若相同直接输出 $0$&lt;/p&gt;
&lt;p&gt;否则用 $for$ 遍历一次字符串&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::string s, t;
	std::cin &gt;&gt; s &gt;&gt; t;
	if (s == t) {
		std::cout &amp;#x3C;&amp;#x3C; 0 &amp;#x3C;&amp;#x3C; endl;
		return;
	}
	for(int i = 0; i &amp;#x3C; std::max(s.size(), t.size()); i++) {
		if (s[i] != t[i]) {
			std::cout &amp;#x3C;&amp;#x3C; i + 1 &amp;#x3C;&amp;#x3C; endl;
			break;
		}
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Separated Lunch&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc374/tasks/abc374_c&quot;&gt;Separated Lunch&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给出一个数 $n$, 和一个长度为 $n$ 的数组 $K$, 将这个数组划分为 $A$ , $B$两个部分,使得这两个部分的和 $S_{A}$ 和 $S_{B}$ 中的最大值最小&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;数据范围:
$2 \leq n \leq 20$,
$1 \leq K_{i} \leq 10^{8}$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;瞄一眼中文题面, 有点像 $01$ 背包, 但是你可以发现数据范围好像不能用背包，有没有其他方法呢?&lt;/p&gt;
&lt;p&gt;好像 $n$ 的范围比较小，我们可以使用 $dfs$ 来搜索每一种情况，最多为 $2^{20}$,那么怎么判断哪种情况最优?只需要满足 $S_{A}$和 $S_{B}$ 的差值最小，答案即为差值最小时的最大值。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, w = 0;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; a(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i];
		w += a[i];
	}


	std::vector&amp;#x3C;int&gt; f(n, 0);
	int mi = inf, ans = inf;
	std::function&amp;#x3C;void(int)&gt; dfs = ([&amp;#x26;](int u) {
		if (u &gt;= n) {
			int s = 0;
			for(int i = 0; i &amp;#x3C; n; i++) {
				if (f[i]) {
					s += a[i];
				}
			}
			if (mi &gt;= abs(w - s - s)) {
				mi = abs(w - s - s);
				ans = std::min(ans, std::max(s, w - s));
			}
			return;
		}
		f[u] = 1;
		dfs(u + 1);
		f[u] = 0;
		dfs(u + 1);
	});

	dfs(0);

	std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Laser Marking&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc374/tasks/abc374_d&quot;&gt;Laser Marking&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;在一个平面上给出 $n$ 条线段的起始点$(A_{i}, B_{i})$和终点$(C_{i}, D_{i})$ 现在要使用激光打印机打印这些线段,在打印线段时的移动速度为每秒 $T$ 个单位长度, 不打印的时候的移动速度为每秒 $S$ 个单位长度, 问打印这些线段的最短时间为多少？&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于一个线段可以从两个端点中的任意一个开始打印，看来这个题又和上面一个题一样使用 $dfs$ ,循环初始到达线段,先移动到其中一个端点,再移动到另一个端点，答案记录下来，再$dfs$, $dfs$函数中的参数 $x$, $y$, $u$, $v$ 表示在此之前是从点$(x,y)$ 移动到了 $(u,v)$.其实 $dfs$ 只传当前位置就行了,只是个人方便识别.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;p&gt;hypot()函数详解：
hypot(x, y) 返回的是浮点型数据类型,值为 $\sqrt{x^{2} + y^{2}}$ 即将$x, y$作为直角三角形的两条直角边的斜边。
hypot(x,y,z) 返回类型同上值为 $\sqrt{x^{2} + y^{2} + z^{2}}$&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, s, t;
	std::cin &gt;&gt; n &gt;&gt; s &gt;&gt; t;
	std::vector&amp;#x3C;int&gt; A(n), B(n), C(n), D(n);
	for(int i = 0; i &amp;#x3C; n; i++)
		std::cin &gt;&gt; A[i] &gt;&gt; B[i] &gt;&gt; C[i] &gt;&gt; D[i];

	std::vector&amp;#x3C;bool&gt; vis(n, false);
	double ans = INFINITY, w = 0;
	auto check = [&amp;#x26;]() -&gt; bool {
		for(int i = 0; i &amp;#x3C; n; i++) if (!vis[i]) return false;
		return true;
	};

	std::function&amp;#x3C;void(int, int, int, int)&gt; dfs = ([&amp;#x26;](int x, int y, int u, int v) -&gt; void {
		if (check()) {
			ans = std::min(ans, w);
//			std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
			return;
		}

		for(int i = 0; i &amp;#x3C; n; i++) {
			if (!vis[i]) {
				vis[i] = true;
				auto t1 = std::hypot(u - A[i], v - B[i]) / s;
				auto t2 = std::hypot(u - C[i], v - D[i]) / s;
				auto tt = std::hypot(A[i] - C[i], B[i] - D[i]) / t;
				w += tt, w += t1;
				dfs(A[i], B[i], C[i], D[i]);
				w -= t1, w += t2;
				dfs(C[i], D[i], A[i], B[i]);
				w -= t2, w -= tt;
				vis[i] = false;
			}
		}
	});

	for(int i = 0; i &amp;#x3C; n; i++) {
		vis[i] = true;
		auto t1 = std::hypot(A[i], B[i]) / s;
		auto t2 = std::hypot(C[i], D[i]) / s;
		auto tt = std::hypot(A[i] - C[i], B[i] - D[i]) / t;
		w = t1 + tt;
		dfs(A[i], B[i], C[i], D[i]);
		w = t2 + tt;
		dfs(C[i], D[i], A[i], B[i]);
		vis[i] = false;
	}
	std::cout &amp;#x3C;&amp;#x3C; fix(16) &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/6.ASC8SSai.webp"/><enclosure url="/_astro/6.ASC8SSai.webp"/></item><item><title>Atcoder beginner contest 375</title><link>https://santisify.top/blog/old/abc375</link><guid isPermaLink="true">https://santisify.top/blog/old/abc375</guid><description>Atcoder abc 375 (A-D)</description><pubDate>Mon, 07 Oct 2024 14:07:03 GMT</pubDate><content:encoded>&lt;h2&gt;A.Seats&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc375/tasks/abc375_a&quot;&gt;Seats&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定字符串 $s$ 其中字符串只含有 &lt;code&gt;#&lt;/code&gt; 和 &lt;code&gt;.&lt;/code&gt; ,&lt;code&gt;#&lt;/code&gt; 表示当前位置有人, &lt;code&gt;.&lt;/code&gt;表示当前位置无人.
问:有多少个位置满足左右有人，当前位置无人的.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::string s;
	std::cin &gt;&gt; s;
	int ct = 0;
	for(int i = 1; i &amp;#x3C; n - 1; i++) {
		if (s[i] == &apos;.&apos; &amp;#x26;&amp;#x26; s[i] != s[i + 1] &amp;#x26;&amp;#x26; s[i + 1] == s[i - 1])
			ct++;
	}
	std::cout &amp;#x3C;&amp;#x3C; ct &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.Traveling Takahashi Problem&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc375/tasks/abc375_b&quot;&gt;Traveling Takahashi Problem&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定$n$个点，从点 $(0,0)$ 出发依次经过这些点,然后回到原点的代价.
从点 $(a,b)$ 移动到点 $(c,d)$ 的代价是 $\sqrt{(a-c)^{2} + (b-d)^{2}}$&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	double s = 0;
	int n;
	std::cin &gt;&gt; n;
	int x = 0, y = 0;
	for(int i = 0; i &amp;#x3C; n; i++) {
		int u, v;
		std::cin &gt;&gt; u &gt;&gt; v;
		s += std::hypot(u - x, y - v);
		x = u, y = v;
	}
	s += std::hypot(x, y);
	std::cout &amp;#x3C;&amp;#x3C; fix(16) &amp;#x3C;&amp;#x3C; s &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.Spiral Rotation&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc375/tasks/abc375_c&quot;&gt;Spiral Rotation&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;题意太复杂，直接说重点，在 $N * N$ 的矩阵中,每个单元格都涂成黑色或白色。如果 $A_{i, j} =$ 则 $(i, j)$ 单元格为黑色；如果是 $A_{i, j} =$ &lt;code&gt;.&lt;/code&gt;，则为黑色。.&quot;，则为白色。&lt;/p&gt;
&lt;p&gt;依次对 $i = 1, 2, \ldots, \frac{N}{2}$ 进行以下操作:&lt;/p&gt;
&lt;p&gt;对于 $i$ 和 $N + 1 - i$ 之间的所有整数对 $x, y$ ，将单元格 $(y, N + 1 - x)$ 的颜色替换为单元格 $(x, y)$ 的颜色。同时对所有这些单元格对 $x, y$ 进行替换。
最后打印这个矩阵。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;稍加推理就可以发现对于每次操作 $i$都是在对以 $(i,i)$为左上角，大小为 $(N-i+1)*(N-i+1)$ 的子矩阵进行顺时针旋转 $90^{\circ}$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;p&gt;TLE code&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; s[i];
	}

	for(int a = 0; a &amp;#x3C; n / 2; a++) {
		auto t = s;
		for(int i = a; i &amp;#x3C; n - a; i++) {
			for(int j = a; j &amp;#x3C; n - a; j++) {
				t[i][j] = s[n - j - 1][i];
			}
		}
		s = t;
	}

	for(auto i : s) {
		std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; endl;
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;AC code&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int N;
	std::cin &gt;&gt; N;
	std::vector&amp;#x3C;std::string&gt; A(N), B(N, std::string(N, &apos; &apos;));
	for(int i = 0; i &amp;#x3C; N; i++)std::cin &gt;&gt; A[i];
	for(int d = 0; d &amp;#x3C; N / 2; d++) {
		for(int t = 0; t &amp;#x3C; (d + 1) % 4; t++) {
			for(int x = d; x &amp;#x3C; N - d; x++) {
				B[x][d] = A[x][d];
				B[x][N - d - 1] = A[x][N - d - 1];
				B[d][x] = A[d][x];
				B[N - d - 1][x] = A[N - d - 1][x];
			}
			for(int x = d; x &amp;#x3C; N - d; x++) {
				A[d][N - x - 1] = B[x][d];
				A[N - d - 1][N - x - 1] = B[x][N - d - 1];
				A[x][N - d - 1] = B[d][x];
				A[x][d] = B[N - d - 1][x];
			}
		}
	}
	for(auto i : A) {
		std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; endl;
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.ABA&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc375/tasks/abc375_d&quot;&gt;ABA&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给你一个由大写英文字母组成的字符串 $S$ 。
求满足以下两个条件的整数三元组 $(i, j, k)$ 的个数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$1 \leq i &amp;#x3C; j &amp;#x3C; k \leq |S|$&lt;/li&gt;
&lt;li&gt;将 $S_i$ 、 $S_j$ 和 $S_k$ 按此顺序连接而成的长度为 $3$ 的字符串是一个回文字符串。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里， $|S|$ 表示 $S$ 的长度， $S_x$ 表示 $S$ 的 $x$ -th字符。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这个其实就是前缀和维护当前位置前的每个字母个数和当前位置后的每个字母个数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::string s;
	std::cin &gt;&gt; s;
	std::vector ct(26, std::vector&amp;#x3C;int&gt;(s.size() + 1, 0ll));
	for(int i = 0; i &amp;#x3C; s.size(); i++) {
		ct[s[i] - &apos;A&apos;][i]++;
	}

	for(int i = 0; i &amp;#x3C; 26; i++) {
		for(int j = 1; j &amp;#x3C; s.size(); j++) {
			ct[i][j] += ct[i][j - 1];
		}
	}
	int ans = 0;
	for(int i = 1; i &amp;#x3C; s.size() - 1; i++) {
		for(int j = 0; j &amp;#x3C; 26; j++) {
			ans += ct[j][i - 1] * (ct[j][s.size() - 1] - ct[j][i]);
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/7.B2ZxFEGq.webp"/><enclosure url="/_astro/7.B2ZxFEGq.webp"/></item><item><title>Codeforces Round 971 (Div.4)</title><link>https://santisify.top/blog/old/cf2009</link><guid isPermaLink="true">https://santisify.top/blog/old/cf2009</guid><description>codeforces-round-971(A-D)</description><pubDate>Wed, 04 Sep 2024 09:18:56 GMT</pubDate><content:encoded>&lt;h2&gt;A. Minimize!&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2009/problem/A&quot;&gt;Minimize!&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs A %}&lt;/p&gt;
&lt;p&gt;You are given two integers a and b (a≤b). Over all possible integer values of c (a≤c≤b), find the minimum value of (c−a)+(b−c).&lt;/p&gt;
&lt;p&gt;给定数字 $a$ , $b$ ,一个数 $c$ 的取值范围为 $[a,b]$ 求 $(c-a)+(b-c)$ 的最小值&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们对等式化简 $(c-a)+(b-c) \to b-a$ 由此可见,等式的结果与 $c$ 的值无关&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int a, b;
	std::cin &gt;&gt; a &gt;&gt; b;
	std::cout &amp;#x3C;&amp;#x3C; b - a &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B.osu!mania&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2009/problem/B&quot;&gt;osu!mania&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs B %}&lt;/p&gt;
&lt;p&gt;You are playing your favorite rhythm game, osu!mania. The layout of your beatmap consists of $n$ rows and &lt;code&gt;4&lt;/code&gt; columns. Because notes at the bottom are closer, you will process the bottommost row first and the topmost row last. Each row will contain exactly one note, represented as a &apos;#&apos;.
For each note 1,2,…,n, in the order of processing, output the column in which the note appears.&lt;/p&gt;
&lt;p&gt;给定 $n$ 行 &lt;code&gt;4&lt;/code&gt; 列的字符串,从下向上处理字符串，输出该行字符串的 &lt;code&gt;#&lt;/code&gt; 的位置&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;中文题面说得很清楚,用&lt;code&gt;STL&lt;/code&gt;中的&lt;code&gt;find&lt;/code&gt;函数就可以了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; s[i];
	}

	for(int i = n - 1; i &gt;= 0; i--) {
		std::cout &amp;#x3C;&amp;#x3C; s[i].find(&apos;#&apos;) + 1 &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == 0];
	}
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C.The Legend of Freya the Frog&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2009/problem/C&quot;&gt;The Legend of Freya the Frog&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs C %}&lt;/p&gt;
&lt;p&gt;Freya the Frog is traveling on the 2D coordinate plane. She is currently at point (0,0) and wants to go to point (x,y). In one move, she chooses an integer d such that 0≤d≤k and jumps d spots forward in the direction she is facing.&lt;/p&gt;
&lt;p&gt;Initially, she is facing the positive x direction. After every move, she will alternate between facing the positive x direction and the positive y direction (i.e., she will face the positive y direction on her second move, the positive x direction on her third move, and so on).&lt;/p&gt;
&lt;p&gt;What is the minimum amount of moves she must perform to land on point (x,y)?&lt;/p&gt;
&lt;p&gt;在一个二维平面中,当前位置处于点 $(0,0)$ , 在给定一个数 $k$,每次移动的距离为 $d (0 \le d \le k) $,并且每次移动方向是在 $x$ 和 $y$ 轴正方向之间交替.
问需要就次移动到达点 $(x,y)$?&lt;/p&gt;
&lt;p&gt;{%endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;分别考虑 $x$ 和 $y$ 两个方向，计算我们在每个方向上需要的跳转次数。我们在 $x$ 方向上需要的跳转数是 $\lceil \frac{x}{k} \rceil$ ，类似地，在 $y$ 方向上需要的跳转数是 $\lceil \frac{y}{k} \rceil$ 。现在，让我们试着将它们组合起来，求出跳转的总次数。让我们考虑以下几种情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$\lceil \frac{y}{k} \rceil \geq \lceil \frac{x}{k} \rceil$ .在这种情况下，需要在 $y$ 方向上进行 $\lceil \frac{y}{k} \rceil - \lceil \frac{x}{k} \rceil$ 次额外跳跃。在弗莱娅执行这些额外跳跃时，她会选择 $x$ 方向的 $d = 0$ 。总共需要 $2 \cdot \lceil \frac{y}{k} \rceil$ 次跳跃。&lt;/li&gt;
&lt;li&gt;$\lceil \frac{x}{k} \rceil &amp;#x3C; \lceil \frac{y}{k} \rceil$ .我们可以使用与前一种情况相同的推理方法，但是有一个问题。由于弗莱娅一开始是朝向 $x$ 方向的，所以在最后一跳时，她不需要朝向 $y$ 方向跳。总共需要 $2 \cdot \lceil \frac{x}{k} \rceil - 1$ 次跳跃。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int x, y, k;
	std::cin &gt;&gt; x &gt;&gt; y &gt;&gt; k;

	x = (x + k - 1) / k;
	y = (y + k - 1) / k;

	std::cout &amp;#x3C;&amp;#x3C; std::max(2 * x - 1, 2 * y) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D.Satyam and Counting&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2009/problem/D&quot;&gt;Satyam and Counting&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs D%}&lt;/p&gt;
&lt;p&gt;Satyam is given $n$ distinct points on the 2D coordinate plane. It is guaranteed that $0 \leq y_i \leq 1$ for all given points $(x_i, y_i)$. How many different nondegenerate right triangles$^{\text{∗}}$ can be formed from choosing three different points as its vertices?
Two triangles $a$ and $b$ are different if there is a point $v$ such that $v$ is a vertex of $a$ but not a vertex of $b$.
$^{\text{∗}}$A nondegenerate right triangle has positive area and an interior $90^{\circ}$ angle.&lt;/p&gt;
&lt;p&gt;给出 $n$ 个点的坐标, 并且点的位置至多两行,数据范围:$(0 \le x_{i} \le n, 0 \le y_{i} \le 1)$,问这些点能组成多少个直角三角形?&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;对于点 $(x,y)$形成直角三角形分为以下情况&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以点 $(x,1-y)$ 为三角形的直角顶点,那么这个情况的三角形的个数为点 ($(x, 1-y)$ 的个数 -1)&lt;/li&gt;
&lt;li&gt;以点 $(x,y)$ 为三角形的直角顶点,我们就需要判断点$(x-1,1-y)$ 和点 $(x+1,1-y)$ 是否存在,若存在则这样的三角形的个数为 $1$&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; x(n, 0ll), y(n, 0ll), cnt(2, 0ll);
	std::vector vis(n + 1, std::array&amp;#x3C;int, 2&gt;{0, 0});
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; x[i] &gt;&gt; y[i];
		cnt[y[i]]++;
		vis[x[i]][y[i]] = 1;
	}

	int res = 0;
	for(int i = 0; i &amp;#x3C; n; i++) {
		if (vis[x[i]][1 - y[i]]) {
			res += cnt[1 - y[i]] - 1;
		}
		if (x[i] &gt; 0 &amp;#x26;&amp;#x26; x[i] &amp;#x3C; n &amp;#x26;&amp;#x26; vis[x[i] - 1][1 - y[i]] &amp;#x26;&amp;#x26; vis[x[i] + 1][1 - y[i]]) {
			res++;
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/1.BgPTuxZz.webp"/><enclosure url="/_astro/1.BgPTuxZz.webp"/></item><item><title>Codeforces Round 967 (Div. 2)</title><link>https://santisify.top/blog/old/cf2001</link><guid isPermaLink="true">https://santisify.top/blog/old/cf2001</guid><description>codeforces-round-967(A-B)</description><pubDate>Mon, 02 Sep 2024 19:26:28 GMT</pubDate><content:encoded>&lt;h2&gt;A.&lt;a href=&quot;https://codeforces.com/contest/2001/problem/A&quot;&gt;Make All Equal&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs A %}&lt;/p&gt;
&lt;p&gt;You are given a cyclic array $a_1,a_2,…,a_n$ .
You can perform the following operation on a at most $n−1$ times:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Let m be the current size of a, you can choose any two adjacent elements where the previous one is no greater than the latter one (In particular, $a_m$ and $a_1$ are adjacent and $a_m$ is the previous one), and delete exactly one of them. In other words, choose an integer i ( $1 \le i \le m$ ) where $a_i \le a_{(i \mod m)+1}$ holds, and delete exactly one of $a_i$ or $a_{(i \mod m) + 1}$ from aa.
Your goal is to find the minimum number of operations needed to make all elements in aa equal.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;题目意思是想让我们用最少的操作次数删除数组中的元素获得数组中的数字全相等的数组。&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于需要最小的操作数，我们可以直接剩下数目最多的数字，于是就可以使用 &lt;code&gt;STL&lt;/code&gt; 中的 &lt;code&gt;map&lt;/code&gt; 完成此题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::map&amp;#x3C;int, int&gt; mp;
	for(int i = 0, x; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; x;
		mp[x]++;
	}

	int res = 0;
	for(auto [x, y] : mp) {
		res = std::max(res, y);
	}
	std::cout &amp;#x3C;&amp;#x3C; n - res &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/16.BVwpR6zr.webp"/><enclosure url="/_astro/16.BVwpR6zr.webp"/></item><item><title>Atcoder beginner contest 367</title><link>https://santisify.top/blog/old/abc367</link><guid isPermaLink="true">https://santisify.top/blog/old/abc367</guid><description>Atcoder abc 367(A-D)</description><pubDate>Sun, 25 Aug 2024 19:30:34 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://atcoder.jp/contests/abc367/tasks/abc367_a&quot;&gt;Shout Everyday&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目&lt;/h3&gt;
&lt;p&gt;给定一个整数时间 &lt;code&gt;A&lt;/code&gt;,一个人在&lt;code&gt;B&lt;/code&gt;时间睡觉,&lt;code&gt;C&lt;/code&gt;时间起床(24小时制),问&lt;code&gt;A&lt;/code&gt;是否不在睡觉时间&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以先判断&lt;code&gt;B&lt;/code&gt;，&lt;code&gt;C&lt;/code&gt;这个时间段是否是跨越两天的，若是跨越两天， &lt;code&gt;A &amp;#x3C; B &amp;#x26;&amp;#x26; A &gt; C&lt;/code&gt; 才会不在这个时间段
若未跨越两天 &lt;code&gt;A &amp;#x3C; B || A &gt; C&lt;/code&gt; 满足不在 &lt;code&gt;B，C&lt;/code&gt; 时间段&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	int a, b, c;
	std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;
	if (b &gt; c) {
		if (a &gt;= b || a &amp;#x3C;= c) {
			std::cout &amp;#x3C;&amp;#x3C; &quot;No&quot; &amp;#x3C;&amp;#x3C; endl;
		} else {
			std::cout &amp;#x3C;&amp;#x3C; &quot;Yes&quot; &amp;#x3C;&amp;#x3C; endl;
		}
	} else {
		if (a &gt;= b &amp;#x26;&amp;#x26; a &amp;#x3C;= c) {
			std::cout &amp;#x3C;&amp;#x3C; &quot;No&quot; &amp;#x3C;&amp;#x3C; endl;
		} else {
			std::cout &amp;#x3C;&amp;#x3C; &quot;Yes&quot; &amp;#x3C;&amp;#x3C; endl;
		}
	}
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://atcoder.jp/contests/abc367/tasks/abc367_b&quot;&gt;Cut .0&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目&lt;/h3&gt;
&lt;p&gt;一个实数 $X$ 已精确到小数点后第三位。
请在下列条件下打印实数 $X$ 。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;小数部分不能有尾数 &quot;0&quot;。&lt;/li&gt;
&lt;li&gt;小数点后不能有多余的尾数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	std::string s, t(&quot;&quot;);
	std::cin &gt;&gt; s;
	int cnt = 0, f = 0;
	for(auto i : s) {
		if (cnt == 3) {
			break;
		}
		cnt += f;
		if (i == &apos;.&apos;) f = 1;
		t = t + i;
	}

	while (t.back() == &apos;0&apos;) t.pop_back();
	if (t.back() == &apos;.&apos;) t.pop_back();
	std::cout &amp;#x3C;&amp;#x3C; t &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://atcoder.jp/contests/abc367/tasks/abc367_c&quot;&gt;Enumerate Sequences&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目&lt;/h3&gt;
&lt;p&gt;按升序排列打印所有满足以下条件的长度为 $N$ 的整数序列。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第 $i$ 个元素介于 $1$ 和 $R_i$ 之间。&lt;/li&gt;
&lt;li&gt;所有元素之和是 $K$ 的倍数。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于每个数都介于$1$和 $R_i$之间，我们可以遍历每个位置的每个数，显然$DFS$可以做到
那么回溯条件是什么呢？
显然是走到第$N$个数，那么答案就只需要验证下这$N$个数的和是否为$K$的倍数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

using VI = std::vector&amp;#x3C;int&gt;;
#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	int n, k;
	std::cin &gt;&gt; n &gt;&gt; k;
	VI a(n);
	std::vector&amp;#x3C;VI&gt; ans;
	for(int i = 0; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i];
	}

	VI w(n, 1ll);
	std::function&amp;#x3C;void (int)&gt; dfs = ([&amp;#x26;] (int u) {
		if (u == n) {
			int res = 0;
			for(auto i : w) res += i;
			if (res % k == 0) ans.push_back(w);
			return;
		}
		for(int i = 1; i &amp;#x3C;= a[u]; i++) {
			w[u] = i;
			dfs(u + 1);
		}
		return;
	});

	dfs(0);

	std::sort(ans.begin(), ans.end(), [&amp;#x26;] (VI aa, VI bb) { return aa &amp;#x3C; bb; });

	for(auto q : ans) {
		for(auto i : q) {
			std::cout &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &apos; &apos;;
		}
		std::cout &amp;#x3C;&amp;#x3C; endl;
	}
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D &lt;a href=&quot;https://atcoder.jp/contests/abc367/tasks/abc367_d&quot;&gt;Pedometer&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目&lt;/h3&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	int N, M;
	std::cin &gt;&gt; N &gt;&gt; M;

	std::vector&amp;#x3C;int&gt; A(N);
	std::vector&amp;#x3C;int&gt; pre(N + 1);
	for(int i = 0; i &amp;#x3C; N; i++) std::cin &gt;&gt; A[i], pre[i + 1] = pre[i] + A[i];

	std::map&amp;#x3C;int, int&gt; cnt;
	int ans = 0;

	const int L = pre[N];

	for(int i = 0, j = 0; i &amp;#x3C; N; i++) {
		ans += cnt[(pre[i] - L % M + M) % M];
		ans += cnt[pre[i] % M]++;
	}

	std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/4.CLnYAiiP.webp"/><enclosure url="/_astro/4.CLnYAiiP.webp"/></item><item><title>Atcoder beginner contest 373</title><link>https://santisify.top/blog/old/abc373</link><guid isPermaLink="true">https://santisify.top/blog/old/abc373</guid><description>Atcoder abc 373(A-C)</description><pubDate>Sun, 25 Aug 2024 19:30:34 GMT</pubDate><content:encoded>&lt;h2&gt;A September&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc373/tasks/abc373_a&quot;&gt;September&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;有 $12$ 个字符串 $S_1, S_2, S_3, \cdots S_{12}$
问有几个字符串满足 $S_{i} = i (1 \le i \le 12)$&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;太简单不需要解释&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int ct = 0;
	for(int i = 0; i &amp;#x3C; 12; i++) {
		std::string s;
		std::cin &gt;&gt; s;
		if (s.size() == i + 1) ct++;
	}
	std::cout &amp;#x3C;&amp;#x3C; ct &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B 1D Keyboard&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc373/tasks/abc373_b&quot;&gt;1D Keyboard&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给定长度为 $26$ 的字符串，并且保证字符串每个英文字母只出现一次,当前第 $0$ 步时处于 $A$ 点, 问需要走多少步会使得字符串所走过的路径为 $ABC.....XYZ$.简单点说就是从 $A$ 点走到 $B$ 点,再到 $C$ 点,以此类推,知道 $Z$ 点,至少需要走多少步?&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于字符串中一个字母只会出现一次,我们就可以将每个字母的位置记录下来,然后再依次算出相邻两个点的距离,即可得出答案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	std::string s;
	std::cin &gt;&gt; s;

	std::map&amp;#x3C;char, int&gt; mp;
	for(int i = 0; i &amp;#x3C; s.size(); i++) {
		mp[s[i]] = i;
	}
	int now = mp[&apos;A&apos;];
	int w = 0;
	mp.erase(&apos;A&apos;);
	for(auto [c, pos] : mp) {
		w += abs(now - pos);
		now = pos;
	}

	std::cout &amp;#x3C;&amp;#x3C; w &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C Max Ai+Bj&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc373/tasks/abc373_c&quot;&gt;Max Ai+Bj&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;给你两个整数序列 $A$ 和 $B$ ，每个长度为 $N$ 。请选择整数 $i, j$ $(1 \leq i, j \leq N)$ 使其长度最大化。 $(1 \leq i, j \leq N)$ 使 $A &lt;em&gt;{i} + B&lt;/em&gt;{j}$ 的值最大。输出最大值。&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;选择尽量大的 $i,j$ 使得 $A_{i} + B_{j}$最大,为了使得和最大,只需要分别选择两个数组的最大值，才能使得和最大。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; a(n), b(n);

	for(int i = 0, x; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; a[i];
	}
	for(int i = 0, x; i &amp;#x3C; n; i++) {
		std::cin &gt;&gt; b[i];
	}
	std::sort(a.begin(), a.end());
	std::sort(b.begin(), b.end());
	std::cout &amp;#x3C;&amp;#x3C; a[n - 1] + b[n - 1] &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/5.OcSOKqon.webp"/><enclosure url="/_astro/5.OcSOKqon.webp"/></item><item><title>Codeforces Round 974 (Div.3)</title><link>https://santisify.top/blog/old/cf2014</link><guid isPermaLink="true">https://santisify.top/blog/old/cf2014</guid><description>codeforces-round-974(A-D)</description><pubDate>Thu, 22 Aug 2024 15:40:48 GMT</pubDate><content:encoded>&lt;h2&gt;A. Robin Helps&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2014/problem/A&quot;&gt;Robin Helps&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs A %}&lt;/p&gt;
&lt;p&gt;There is a little bit of the outlaw in everyone, and a little bit of the hero too. The heroic outlaw Robin Hood is famous for taking from the rich and giving to the poor. Robin encounters n people starting from the 1\-st and ending with the n\-th. The i\-th person has ai gold. If ai≥k, Robin will take all ai gold, and if ai\=0, Robin will give 1 gold if he has any. Robin starts with 0 gold. Find out how many people Robin gives gold to.&lt;/p&gt;
&lt;p&gt;给定 $n$ 和 $k$ ,和一个长度为 $n$ 的数组 $a$ ,金币初始值为 &lt;code&gt;0&lt;/code&gt; 当 $a_{i} \ge k$ 时,会将 $a_{i}$ 全部取走(即金币数+$a_{i}$), 若 $a_{i}=0$ 并且金币数不为 &lt;code&gt;0&lt;/code&gt; 那么会给他一个金币,问最后给了多少人金币?&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;其实只需要将过程模拟下即可&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, k;
	std::cin &gt;&gt; n &gt;&gt; k;
	std::vector&amp;#x3C;int&gt; a(n);
	for(int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
	int s = 0, cnt = 0;
	for(int i = 0; i &amp;#x3C; n; i++) {
		if (a[i] &gt;= k) {
			s += a[i];
		}
		if (a[i] == 0 &amp;#x26;&amp;#x26; s) {
			s -= 1;
			cnt++;
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; cnt &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B. Robin Hood and the Major Oak&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2014/problem/B&quot;&gt;Robin Hood and the Major Oak&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs B %}&lt;/p&gt;
&lt;p&gt;In Sherwood, the trees are our shelter, and we are all children of the forest.&lt;/p&gt;
&lt;p&gt;The Major Oak in Sherwood is known for its majestic foliage, which provided shelter to Robin Hood and his band of merry men and women.&lt;/p&gt;
&lt;p&gt;The Major Oak grows ii new leaves in the i-th year. It starts with 1 leaf in year 1.&lt;/p&gt;
&lt;p&gt;Leaves last for k years on the tree. In other words, leaves grown in year i last between years i and i+k−1 inclusive.&lt;/p&gt;
&lt;p&gt;Robin considers even numbers lucky. Help Robin determine whether the Major Oak will have an even number of leaves in year n.&lt;/p&gt;
&lt;p&gt;大橡树在第(i)年会长出两片新叶。第 1 年开始长 1 片叶子。&lt;/p&gt;
&lt;p&gt;树叶在树上可以存活 k 年。换句话说，第 i 年长出的树叶在第 i 年和第 i+k-1 年(包括第 i+k-1 年)之间持续生长。&lt;/p&gt;
&lt;p&gt;罗宾认为偶数是幸运数字。请帮助罗宾判断这棵橡树在第 n 年的叶子数是否为偶数。&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;p&gt;==数据范围:==&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;$$
1 \le n \le 10^{9}, 1 \le k \le n
$$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于一片树叶的存活期为 $k$ 我们不妨只看后面 $k$ 年的树叶, 对于第 $i$ 年的树叶数量为 $i^ {i}$ ,但是数据范围较大,容易 &lt;code&gt;TLE&lt;/code&gt; 或者是爆 &lt;code&gt;longlong&lt;/code&gt; ,怎么办呢? 我们可以观察出一个性质: 相同奇偶性的底数和指数的结果奇偶性不变,那么就可以将这个问题化解为 $[n-k+1, n]$ 这个区间的所有数的和&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, k;
	std::cin &gt;&gt; n &gt;&gt; k;
	int l = n - k + 1, r = n;
	int s = (l + r) * k / 2;
	if (s &amp;#x26; 1) std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
	else std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;C. Robin Hood in Town&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/2014/problem/C&quot;&gt;Robin Hood in Town&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;p&gt;{% tabs C %}&lt;/p&gt;
&lt;p&gt;There are &lt;strong&gt;n&lt;/strong&gt; people living in the town. Just now, the wealth of the &lt;strong&gt;i&lt;/strong&gt;-th person was &lt;strong&gt;a&lt;/strong&gt;i gold. But guess what? The richest person has found an extra pot of gold!&lt;/p&gt;
&lt;p&gt;More formally, find an &lt;strong&gt;a&lt;/strong&gt;j**=&lt;strong&gt;m&lt;/strong&gt;a&lt;strong&gt;x&lt;/strong&gt;(&lt;strong&gt;a&lt;/strong&gt;1**,&lt;strong&gt;a&lt;/strong&gt;2**,&lt;strong&gt;…&lt;/strong&gt;,&lt;strong&gt;a&lt;/strong&gt;n**), change &lt;strong&gt;a&lt;/strong&gt;j to &lt;strong&gt;a&lt;/strong&gt;j**+**x, where &lt;strong&gt;x&lt;/strong&gt; is a non-negative integer number of gold found in the pot. If there are multiple maxima, it can be any one of them.&lt;/p&gt;
&lt;p&gt;A person is unhappy if their wealth is &lt;strong&gt;strictly less than half&lt;/strong&gt; of the average wealth**∗**.&lt;/p&gt;
&lt;p&gt;If &lt;strong&gt;strictly more than half&lt;/strong&gt; of the total population &lt;strong&gt;n&lt;/strong&gt; are unhappy, Robin Hood will appear by popular demand.&lt;/p&gt;
&lt;p&gt;Determine the minimum value of &lt;strong&gt;x&lt;/strong&gt; for Robin Hood to appear, or output **−**1 if it is impossible.&lt;/p&gt;
&lt;p&gt;给定长度为 $n$ 的数组 $a$ ,现在要将数 $x$ 加在数组中的最大值上,使得整个数组中小于平均值的一半的数目大于 $\frac{n}{2}$ ,问数 $x$ 的最小值为多少?&lt;/p&gt;
&lt;p&gt;{% endtabs %}&lt;/p&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;打眼一看,二分没问题了
已知是将 $x$ 加在最大值上,那么我们可以将数组进行排序,为了使得满足条件 $a_{i}&amp;#x3C;\frac{\sum_{i=1}^{n}a_{i}}{n&lt;em&gt;2}$ 的数目大于 $\frac{n}{2}$ 那么就只需要在排序好的数组中找到前 $\frac{n}{2}$ 个最小值,只要这其中的最大值都比 $\frac{\sum_{i=1}^{n}a_{i}}{n&lt;/em&gt;2}$ 小,就可以满足条件.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve() {
	int n, s = 0;
	std::cin &gt;&gt; n;
	std::vector&amp;#x3C;int&gt; a(n);
	for(int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i], s += a[i];
	if (n &amp;#x3C;= 2) {
		std::cout &amp;#x3C;&amp;#x3C; -1 &amp;#x3C;&amp;#x3C; endl;
		return;
	}
	std::sort(a.begin(), a.end());
	std::function&amp;#x3C;bool(int)&gt; check = ([&amp;#x26;](int x) -&gt; bool {
		int cnt = 0;
		double t = (s + x * 1.0 ) / (n * 2);
		return a[n / 2] &amp;#x3C; t;
	});

	int l = 0, r = 1e16;
	while (l &amp;#x3C; r) {
		int mid = (l + r) &gt;&gt; 1;
		if (check(mid)) {
			r = mid;
		} else {
			l = mid + 1;
		}
	}

	std::cout &amp;#x3C;&amp;#x3C; l &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/2.B6SRnO5S.webp"/><enclosure url="/_astro/2.B6SRnO5S.webp"/></item><item><title>Atcoder beginner contest 339</title><link>https://santisify.top/blog/old/abc339</link><guid isPermaLink="true">https://santisify.top/blog/old/abc339</guid><description>Atcoder abc 339(A-B)</description><pubDate>Thu, 15 Aug 2024 18:43:36 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://atcoder.jp/contests/abc339/tasks/abc339_a&quot;&gt;TLD&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定字符串&lt;code&gt;s&lt;/code&gt;,输出字符串中&lt;code&gt;.&lt;/code&gt;(点)后面的字符,若有多个&lt;code&gt;.&lt;/code&gt;输出最后一个&lt;code&gt;.&lt;/code&gt;的信息.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有多种解法,可以暴力循环一次,或者用&lt;code&gt;find()&lt;/code&gt;函数查找&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e9 + 1;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    int pos = 0, t = -1;
    while ((pos = s.find(&apos;.&apos;, pos)) != -1)
        t = pos, pos++;
    std::cout &amp;#x3C;&amp;#x3C; s.substr(t + 1) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://atcoder.jp/contests/abc339/tasks/abc339_b&quot;&gt;Langton&apos;s Takahashi &lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给三个数&lt;code&gt;n&lt;/code&gt;,&lt;code&gt;m&lt;/code&gt;和&lt;code&gt;k&lt;/code&gt;,其中&lt;code&gt;n&lt;/code&gt; &lt;code&gt;m&lt;/code&gt;代表&lt;code&gt;n * m&lt;/code&gt;的矩阵,&lt;code&gt;k&lt;/code&gt;代表操作数
起始点在矩阵的&lt;code&gt;(1,1)&lt;/code&gt;,朝向为正上方
对于每次操作:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;当前位置为&lt;code&gt;.&lt;/code&gt; 则将当前位置改为&lt;code&gt;#&lt;/code&gt; 并且向右转,向前走一步.&lt;/li&gt;
&lt;li&gt;当前位置为&lt;code&gt;#&lt;/code&gt; 则将当前位置改为&lt;code&gt;.&lt;/code&gt; 并且向左转,向前走一步.
打印出矩阵作为结果&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;使用矩阵模拟下过程即可
对于样例&lt;code&gt;3  4  5&lt;/code&gt;模拟下
初始状态&lt;code&gt;x = 1, y = 1&lt;/code&gt;朝向正上方&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;$$
\begin{matrix}
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;第一步,由于当前位置&lt;code&gt;(1,1)&lt;/code&gt;为&lt;code&gt;.&lt;/code&gt;那么就需要将当前位置变为&lt;code&gt;#&lt;/code&gt;,并向右转,走一步到&lt;code&gt;(1,2)&lt;/code&gt;,朝向右&lt;/p&gt;
&lt;p&gt;$$
\begin{matrix}
#&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;第二步,由于当前位置&lt;code&gt;(1,2)&lt;/code&gt;为&lt;code&gt;.&lt;/code&gt;那么就需要将当前位置变为&lt;code&gt;#&lt;/code&gt;,并向右转,走一步到&lt;code&gt;(2,2)&lt;/code&gt;,朝向下&lt;/p&gt;
&lt;p&gt;$$
\begin{matrix}
#&amp;#x26;#&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;第三步,由于当前位置&lt;code&gt;(2,2)&lt;/code&gt;为&lt;code&gt;.&lt;/code&gt;那么就需要将当前位置变为&lt;code&gt;#&lt;/code&gt;,并向右转,走一步到&lt;code&gt;(2,2)&lt;/code&gt;,朝向左&lt;/p&gt;
&lt;p&gt;$$
\begin{matrix}
#&amp;#x26;#&amp;#x26;.\
.&amp;#x26;#&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;第四步,由于当前位置&lt;code&gt;(2,1)&lt;/code&gt;为&lt;code&gt;.&lt;/code&gt;那么就需要将当前位置变为&lt;code&gt;#&lt;/code&gt;,并向右转,走一步到&lt;code&gt;(1,1)&lt;/code&gt;,朝向上&lt;/p&gt;
&lt;p&gt;$$
\begin{matrix}
#&amp;#x26;#&amp;#x26;.\
#&amp;#x26;#&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;第五步,由于当前位置&lt;code&gt;(1,1)&lt;/code&gt;为&lt;code&gt;#&lt;/code&gt;那么就需要将当前位置变为&lt;code&gt;.&lt;/code&gt;,并向左转,走一步到&lt;code&gt;(1,3)&lt;/code&gt;,朝向左
,此处能到&lt;code&gt;(1,3)&lt;/code&gt;是因为矩阵相当于上下,左右连通的.&lt;/p&gt;
&lt;p&gt;$$
\begin{matrix}
.&amp;#x26;#&amp;#x26;.\
#&amp;#x26;#&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
.&amp;#x26;.&amp;#x26;.\
\end{matrix}
$$&lt;/p&gt;
&lt;p&gt;最后就得到了这样的矩阵.对于朝向的转换就需要一定的技巧,合理运用模&lt;code&gt;(mod)&lt;/code&gt;的运算.&lt;/p&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e9 + 1;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n, m, k;
    std::cin &gt;&gt; n &gt;&gt; m &gt;&gt; k;
    std::vector&amp;#x3C;std::string&gt; s(n, std::string(m, &apos;.&apos;));
    int x = 0, y = 0;
    int dx[] = {0, 1, 0, -1},
            dy[] = {1, 0, -1, 0};
    int t = 3;
    while (k--) {
        if (s[x][y] == &apos;.&apos;)
            s[x][y] = &apos;#&apos;, t = (t + 1) % 4;
        else
            s[x][y] = &apos;.&apos;, t = (t + 3) % 4;
        x = (x + n + dx[t]) % n;
        y = (y + m + dy[t]) % m;
    }
    for (int i = 0; i &amp;#x3C; n; i++)
        std::cout &amp;#x3C;&amp;#x3C; s[i] &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/3.D9oyeTVT.webp"/><enclosure url="/_astro/3.D9oyeTVT.webp"/></item><item><title>Atcoder beginner contest 338</title><link>https://santisify.top/blog/old/abc338</link><guid isPermaLink="true">https://santisify.top/blog/old/abc338</guid><description>Atcoder abc 338(A-C)</description><pubDate>Thu, 15 Aug 2024 18:37:21 GMT</pubDate><content:encoded>&lt;h2&gt;A Capitalized?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc338/tasks/abc338_a&quot;&gt;Capitalized?&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个字符串&lt;code&gt;s&lt;/code&gt;, 让我们判断是否满足首字母大写,其他字母小写的规则.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;直接用库函数&lt;code&gt;islower()&lt;/code&gt;和&lt;code&gt;isupper()&lt;/code&gt;模拟一下&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

//#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 2e18 + 50, MOD = 10007;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    if (islower(s[0])) {
        std::cout &amp;#x3C;&amp;#x3C; &quot;No\n&quot;;
        return;
    }
    for (int i = 1; i &amp;#x3C; s.size(); i++)
        if (isupper(s[i])) {
            std::cout &amp;#x3C;&amp;#x3C; &quot;No\n&quot;;
            return;
        }

    std::cout &amp;#x3C;&amp;#x3C; &quot;Yes\n&quot;;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B &lt;a href=&quot;https://atcoder.jp/contests/abc338/tasks/abc338_b&quot;&gt;Frequency&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一字符串&lt;code&gt;s&lt;/code&gt;, 输出出现次数最多字符,若有多个输出字典序较小的.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以用数据结构&lt;code&gt;map&lt;/code&gt;来存储,并记录最大的数.
由于&lt;code&gt;map&lt;/code&gt;会自动将键按从小到大排序,那么我们就只需要遍历一次&lt;code&gt;map&lt;/code&gt;的数据,当遍历到次数与最大值相同时,直接输出字符即可.
同样,用其他的方法计数也可行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 2e18 + 50, MOD = 10007;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    int ma = 0;
    std::map&amp;#x3C;char, int&gt; mp;
    for (auto i: s)
        mp[i]++, ma = std::max(ma, mp[i]);
    for (auto i: mp) {
        if (i.second == ma) {
            std::cout &amp;#x3C;&amp;#x3C; i.first &amp;#x3C;&amp;#x3C; endl;
            return;
        }
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://atcoder.jp/contests/abc338/tasks/abc338_c&quot;&gt;Leftover Recipes&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们现在有&lt;code&gt;n&lt;/code&gt;中配料,分别有$q_i$, 我们需要完成两种菜,这两个菜所用的配料分别$a_i,b_i$
问:我们最多能做多少个菜?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;假设我们做&lt;code&gt;x&lt;/code&gt;个&lt;code&gt;A&lt;/code&gt;菜,&lt;code&gt;y&lt;/code&gt;个&lt;code&gt;B&lt;/code&gt;菜,所花费的各个材料为$a_{i}&lt;em&gt;x + b_i&lt;/em&gt;y$,由于&lt;code&gt;n&lt;/code&gt;
的数据范围较小,我们可以直接暴力循环$x\le10^6$ ,然后判断下$p_i&amp;#x3C;a_i*x$和$b_i$就行了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 2e18 + 50, MOD = 10007;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; q(n);
    auto a = q, b = q;
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; q[i];
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; b[i];
    int ans = 0;
    for (int x = 0; x &amp;#x3C;= 1e6; x++){
        int y = INF;
        for(int i = 0; i &amp;#x3C; n; i ++){
            if(q[i] &amp;#x3C; 1ll * a[i] * x)
                y = -INF;
            else if(b[i] &gt; 0)
                y = std::min(y, (q[i] - a[i] * x) / b[i]);
        }
        ans = std::max(ans, x + y);
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/2.CC9RmHu9.webp"/><enclosure url="/_astro/2.CC9RmHu9.webp"/></item><item><title>Atcoder beginner contest 331</title><link>https://santisify.top/blog/old/abc331</link><guid isPermaLink="true">https://santisify.top/blog/old/abc331</guid><description>Atcoder abc 331(A-C)</description><pubDate>Thu, 15 Aug 2024 18:33:03 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://atcoder.jp/contests/abc331/tasks/abc331_a&quot;&gt;Tomorrow&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;一年由 &lt;code&gt;M&lt;/code&gt;个月组成,从 &lt;code&gt;1&lt;/code&gt;月到 &lt;code&gt;M&lt;/code&gt;月，每个月由 &lt;code&gt;D&lt;/code&gt;天组成，从 &lt;code&gt;1&lt;/code&gt;天到 &lt;code&gt;D&lt;/code&gt;天。
问:在该日历中，年 &lt;code&gt;y&lt;/code&gt;、月 &lt;code&gt;m&lt;/code&gt;、日 &lt;code&gt;d&lt;/code&gt;的下一天的日期？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve(){
    int M, D;
    std::cin &gt;&gt; M &gt;&gt; D;
    int y, m, d;
    std::cin &gt;&gt; y &gt;&gt; m &gt;&gt; d;
    d ++;
    if(d &gt; D){
        d -= D;
        m ++;
        if(m &gt; M){
            m -= M;
            y ++;
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; y &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; m &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; d &amp;#x3C;&amp;#x3C; endl;;
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://atcoder.jp/contests/abc331/tasks/abc331_b&quot;&gt;Buy One Carton of Milk&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;一包 &lt;code&gt;6&lt;/code&gt;个蛋 &lt;code&gt;S&lt;/code&gt;元, 一包 &lt;code&gt;8&lt;/code&gt;个蛋 &lt;code&gt;M&lt;/code&gt;元,一包 &lt;code&gt;12&lt;/code&gt;个蛋 &lt;code&gt;L&lt;/code&gt;元
问:购买任意数量的每包鸡蛋时, 求至少购买 &lt;code&gt;N&lt;/code&gt;个鸡蛋所需的最小价格?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于数据量比较小,我们可以直接三重循环暴力跑一遍.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n, s, m, l;
    std::cin &gt;&gt; n &gt;&gt; s &gt;&gt; m &gt;&gt; l;
    int ans = INF;
    for(int i = 0 ; i &amp;#x3C;=100 ; i ++){
        for(int j = 0; j &amp;#x3C;= 100; j ++){
            for(int k = 0 ; k &amp;#x3C;= 100; k ++){
                int w = i * s + j * m + l * k;
                if(i * 6 + 8 * j + 12 * k &gt;= n)
                    ans = std::min (ans, w);
            }
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://atcoder.jp/contests/abc331/tasks/abc331_c&quot;&gt;Sum of Numbers Greater Than Me&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个大小为 &lt;code&gt;N&lt;/code&gt;的数组 &lt;code&gt;A&lt;/code&gt;,
问: 数组 &lt;code&gt;A&lt;/code&gt;中所有大于 &lt;code&gt;A[i]&lt;/code&gt;的元素之和.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;B&lt;/code&gt;数组为输入的数组, 现有 &lt;code&gt;s&lt;/code&gt;记录数组元素的总和,数组 &lt;code&gt;A&lt;/code&gt;记录 &lt;code&gt;B&lt;/code&gt;数组中大小为 &lt;code&gt;i&lt;/code&gt;的
元素个数为 &lt;code&gt;A[i]&lt;/code&gt;个,我们在遍历一次 &lt;code&gt;A&lt;/code&gt;数组,只要 &lt;code&gt;A[i] &gt; 0&lt;/code&gt;就可以将 &lt;code&gt;A[i]&lt;/code&gt;赋值为 &lt;code&gt;s - A[i] * i&lt;/code&gt;
当然,同时 &lt;code&gt;s -= i * A[i]&lt;/code&gt;
最后,再遍历一次数组 &lt;code&gt;B&lt;/code&gt;,输出 &lt;code&gt;A[B[i]]&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n, s = 0, ans = 0,x;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(1e6 + 50, 0ll), b(n, 0ll);
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cin &gt;&gt; b[i], a[b[i]] ++, s += b[i];

    for(int i = 1 ; i &amp;#x3C;= 1000000 ;i ++){
        if(a[i]){
            s -= a[i] * i;
            a[i] = s;
        }
    }
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cout &amp;#x3C;&amp;#x3C; a[b[i]] &amp;#x3C;&amp;#x3C; &quot; &quot;;

}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/1.BcdCEwMr.webp"/><enclosure url="/_astro/1.BcdCEwMr.webp"/></item><item><title>jiangly算法模板收集</title><link>https://santisify.top/blog/old/jiangly-template</link><guid isPermaLink="true">https://santisify.top/blog/old/jiangly-template</guid><description>jly在cf比赛上的模板</description><pubDate>Thu, 08 Aug 2024 23:52:44 GMT</pubDate><content:encoded>&lt;h1&gt;声明&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2024.03.31&lt;/strong&gt; Update：新增《Splay（其三）》。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;历史更新记录&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2024.02.21&lt;/strong&gt; Update：文件层级重构，新增《后缀自动机（SuffixAutomaton 旧版）》、《回文自动机（PAM）》&lt;/p&gt;
&lt;p&gt;龙年快乐~&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2023.12.29&lt;/strong&gt; Update：新增《树状数组（Fenwick 新版）》。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2023.12.16&lt;/strong&gt; Update：新增《库函数重载》《二项式（Binomial 任意模数计算）》《线性基（Basis）》《线段树（其四）》《Splay（其二）》。&lt;/p&gt;
&lt;p&gt;欢迎通过各种渠道向我投稿~&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;2023.11.02 Update：最新版本都更新在 &lt;a href=&quot;https://github.com/hh2048/XCPC/tree/main/03%20-%20jiangly%E6%A8%A1%E6%9D%BF%E6%94%B6%E9%9B%86&quot;&gt;GitHub&lt;/a&gt; 了，但是注意到有些群u貌似不方便Fan Qiang，于是现在跟进上了 GitHub 的项目进度。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自用！非本人原创，仅作整理归档。大部分代码来自于 &lt;a href=&quot;https://codeforces.com/submissions/jiangly&quot;&gt;CodeForces Jiangly&lt;/a&gt; 的提交，部分来自于GYM、牛客、Atcoder。&lt;a href=&quot;https://www.cnblogs.com/WIDA/p/17633758.html&quot;&gt;文章博客链接&lt;/a&gt;，&lt;a href=&quot;https://github.com/hh2048/XCPC/tree/main/03%20-%20jiangly%E6%A8%A1%E6%9D%BF%E6%94%B6%E9%9B%86&quot;&gt;文章 GitHub 链接&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;灵感参考链接：&lt;a href=&quot;https://github.com/beiyouwuyanzu/cf_code_jiangly&quot;&gt;beiyouwuyanzu/cf_code_jiangly&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h1&gt;目录&lt;/h1&gt;
&lt;p&gt;目录&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A3%B0%E6%98%8E&quot;&gt;声明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%9B%AE%E5%BD%95&quot;&gt;目录&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%B8%80%E6%9D%82%E7%B1%BB&quot;&gt;一、杂类&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#01---int128-%E8%BE%93%E5%87%BA%E6%B5%81%E8%87%AA%E5%AE%9A%E4%B9%89&quot;&gt;01 - int128 输出流自定义&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#02---%E5%B8%B8%E7%94%A8%E5%BA%93%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD&quot;&gt;02 - 常用库函数重载&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BA%8C%E5%9B%BE%E4%B8%8E%E7%BD%91%E7%BB%9C&quot;&gt;二、图与网络&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#01---%E5%BC%BA%E8%BF%9E%E9%80%9A%E5%88%86%E9%87%8F%E7%BC%A9%E7%82%B9scc&quot;&gt;01 - 强连通分量缩点（SCC）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#02---%E5%89%B2%E8%BE%B9%E4%B8%8E%E5%89%B2%E8%BE%B9%E7%BC%A9%E7%82%B9ebcc&quot;&gt;02 - 割边与割边缩点（EBCC）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03---%E4%BA%8C%E5%88%86%E5%9B%BE%E6%9C%80%E5%A4%A7%E6%9D%83%E5%8C%B9%E9%85%8Dmaxassignment-%E5%9F%BA%E4%BA%8Ekm%E4%B9%85%E8%BF%9C&quot;&gt;03 - 二分图最大权匹配（MaxAssignment 基于KM）【久远】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04---%E4%B8%80%E8%88%AC%E5%9B%BE%E6%9C%80%E5%A4%A7%E5%8C%B9%E9%85%8Dgraph-%E5%B8%A6%E8%8A%B1%E6%A0%91%E7%AE%97%E6%B3%95%E4%B9%85%E8%BF%9C&quot;&gt;04 - 一般图最大匹配（Graph 带花树算法）【久远】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#05---twosat2-sat&quot;&gt;05 - TwoSat（2-Sat）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06a---%E6%9C%80%E5%A4%A7%E6%B5%81flow-%E6%97%A7%E7%89%88%E5%85%B6%E4%B8%80%E6%95%B4%E6%95%B0%E5%BA%94%E7%94%A8&quot;&gt;06A - 最大流（Flow 旧版其一，整数应用）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06b---%E6%9C%80%E5%A4%A7%E6%B5%81flow-%E6%97%A7%E7%89%88%E5%85%B6%E4%BA%8C%E6%B5%AE%E7%82%B9%E6%95%B0%E5%BA%94%E7%94%A8&quot;&gt;06B - 最大流（Flow 旧版其二，浮点数应用）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06c---%E6%9C%80%E5%A4%A7%E6%B5%81maxflow-%E6%96%B0%E7%89%88&quot;&gt;06C - 最大流（MaxFlow 新版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#07a---%E8%B4%B9%E7%94%A8%E6%B5%81mcfgraph-%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8%E5%8F%AF%E8%A1%8C%E6%B5%81&quot;&gt;07A - 费用流（MCFGraph 最小费用可行流）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#07b---%E8%B4%B9%E7%94%A8%E6%B5%81mcfgraph-%E6%9C%80%E5%B0%8F%E8%B4%B9%E7%94%A8%E6%9C%80%E5%A4%A7%E6%B5%81&quot;&gt;07B - 费用流（MCFGraph 最小费用最大流）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#08---%E6%A0%91%E9%93%BE%E5%89%96%E5%88%86hld&quot;&gt;08 - 树链剖分（HLD）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%B8%89%E6%95%B0%E8%AE%BA%E5%87%A0%E4%BD%95%E5%A4%9A%E9%A1%B9%E5%BC%8F&quot;&gt;三、数论、几何、多项式&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#01---%E5%BF%AB%E9%80%9F%E5%B9%82&quot;&gt;01 - 快速幂&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#02---%E6%AC%A7%E6%8B%89%E7%AD%9B&quot;&gt;02 - 欧拉筛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03---%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%87%BD%E6%95%B0%E7%AD%9B%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%87%BD%E6%95%B0%E5%8F%8D%E6%BC%94&quot;&gt;03 - 莫比乌斯函数筛（莫比乌斯函数/反演）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04---%E6%B1%82%E8%A7%A3%E5%8D%95%E4%B8%AA%E6%95%B0%E7%9A%84%E6%AC%A7%E6%8B%89%E5%87%BD%E6%95%B0&quot;&gt;04 - 求解单个数的欧拉函数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#05---%E6%89%A9%E5%B1%95%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%97exgcd&quot;&gt;05 - 扩展欧几里得（exGCD）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06---%E7%BB%84%E5%90%88%E6%95%B0combmint--mlong&quot;&gt;06 - 组合数（Comb+MInt &amp;#x26; MLong）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#07---%E4%BA%8C%E9%A1%B9%E5%BC%8Fbinomial-%E4%BB%BB%E6%84%8F%E6%A8%A1%E6%95%B0%E8%AE%A1%E7%AE%97&quot;&gt;07 - 二项式（Binomial 任意模数计算）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#08---%E7%B4%A0%E6%95%B0%E6%B5%8B%E8%AF%95%E4%B8%8E%E5%9B%A0%E5%BC%8F%E5%88%86%E8%A7%A3miller-rabin--pollard-rho&quot;&gt;08 - 素数测试与因式分解（Miller-Rabin &amp;#x26; Pollard-Rho）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#09---%E5%B9%B3%E9%9D%A2%E5%87%A0%E4%BD%95&quot;&gt;09 - 平面几何&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#10---%E9%9D%99%E6%80%81%E5%87%B8%E5%8C%85&quot;&gt;10 - 静态凸包&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#11a---%E5%A4%9A%E9%A1%B9%E5%BC%8F%E7%9B%B8%E5%85%B3poly-%E6%97%A7%E7%89%88&quot;&gt;11A - 多项式相关（Poly 旧版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#11b---%E5%A4%9A%E9%A1%B9%E5%BC%8F%E7%9B%B8%E5%85%B3polymint--mlong-%E6%96%B0%E7%89%88&quot;&gt;11B - 多项式相关（Poly+MInt &amp;#x26; MLong 新版）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9B%9B%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84&quot;&gt;四、数据结构&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#01a---%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84fenwick-%E6%97%A7%E7%89%88&quot;&gt;01A - 树状数组（Fenwick 旧版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#01b---%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84fenwick-%E6%96%B0%E7%89%88&quot;&gt;01B - 树状数组（Fenwick 新版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#02---%E5%B9%B6%E6%9F%A5%E9%9B%86dsu&quot;&gt;02 - 并查集（DSU）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03a---%E7%BA%BF%E6%AE%B5%E6%A0%91segmenttree-%E5%9F%BA%E7%A1%80%E5%8C%BA%E9%97%B4%E5%8A%A0%E4%B9%98&quot;&gt;03A - 线段树（SegmentTree 基础区间加乘）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03b---%E7%BA%BF%E6%AE%B5%E6%A0%91segmenttreeinfo-%E6%9F%A5%E6%89%BE%E5%89%8D%E9%A9%B1%E5%90%8E%E7%BB%A7&quot;&gt;03B - 线段树（SegmentTree+Info 查找前驱后继）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03c---%E7%BA%BF%E6%AE%B5%E6%A0%91segmenttreeinfomerge-%E5%8C%BA%E9%97%B4%E5%90%88%E5%B9%B6&quot;&gt;03C - 线段树（SegmentTree+Info+Merge 区间合并）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04a---%E6%87%92%E6%A0%87%E8%AE%B0%E7%BA%BF%E6%AE%B5%E6%A0%91lazysegmenttree-%E5%9F%BA%E7%A1%80%E5%8C%BA%E9%97%B4%E4%BF%AE%E6%94%B9&quot;&gt;04A - 懒标记线段树（LazySegmentTree 基础区间修改）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04b---%E6%87%92%E6%A0%87%E8%AE%B0%E7%BA%BF%E6%AE%B5%E6%A0%91lazysegmenttree-%E6%9F%A5%E6%89%BE%E5%89%8D%E9%A9%B1%E5%90%8E%E7%BB%A7&quot;&gt;04B - 懒标记线段树（LazySegmentTree 查找前驱后继）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04c---%E6%87%92%E6%A0%87%E8%AE%B0%E7%BA%BF%E6%AE%B5%E6%A0%91lazysegmenttree-%E4%BA%8C%E5%88%86%E4%BF%AE%E6%94%B9&quot;&gt;04C - 懒标记线段树（LazySegmentTree 二分修改）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#05a---%E5%8F%96%E6%A8%A1%E7%B1%BBmlong--mint&quot;&gt;05A - 取模类（MLong &amp;#x26; MInt）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#05b---%E5%8F%96%E6%A8%A1%E7%B1%BBmlong--mint-%E6%96%B0%E7%89%88&quot;&gt;05B - 取模类（MLong &amp;#x26; MInt 新版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06---%E7%8A%B6%E5%8E%8Brmqrmq&quot;&gt;06 - 状压RMQ（RMQ）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#07---splay&quot;&gt;07 - Splay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#08---%E5%85%B6%E4%BB%96%E5%B9%B3%E8%A1%A1%E6%A0%91&quot;&gt;08 - 其他平衡树&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#09---%E5%88%86%E6%95%B0%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97frac&quot;&gt;09 - 分数四则运算（Frac）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#10---%E7%BA%BF%E6%80%A7%E5%9F%BAbasis&quot;&gt;10 - 线性基（Basis）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BA%94%E5%AD%97%E7%AC%A6%E4%B8%B2&quot;&gt;五、字符串&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#01---%E9%A9%AC%E6%8B%89%E8%BD%A6manacher&quot;&gt;01 - 马拉车（Manacher）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#02---z%E5%87%BD%E6%95%B0&quot;&gt;02 - Z函数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#03---%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84sa&quot;&gt;03 - 后缀数组（SA）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04a---%E5%90%8E%E7%BC%80%E8%87%AA%E5%8A%A8%E6%9C%BAsuffixautomaton-%E6%97%A7%E7%89%88&quot;&gt;04A - 后缀自动机（SuffixAutomaton 旧版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#04b---%E5%90%8E%E7%BC%80%E8%87%AA%E5%8A%A8%E6%9C%BAsam-%E6%96%B0%E7%89%88&quot;&gt;04B - 后缀自动机（SAM 新版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#05---%E5%9B%9E%E6%96%87%E8%87%AA%E5%8A%A8%E6%9C%BApam&quot;&gt;05 - 回文自动机（PAM）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06a---ac%E8%87%AA%E5%8A%A8%E6%9C%BAac-%E6%97%A7%E7%89%88&quot;&gt;06A - AC自动机（AC 旧版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#06b---ac%E8%87%AA%E5%8A%A8%E6%9C%BAahocorasick-%E6%96%B0%E7%89%88&quot;&gt;06B - AC自动机（AhoCorasick 新版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#07---%E9%9A%8F%E6%9C%BA%E7%94%9F%E6%88%90%E6%A8%A1%E5%BA%95-%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%93%88%E5%B8%8C%E4%BE%8B%E9%A2%98&quot;&gt;07 - 随机生成模底 字符串哈希（例题）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h1&gt;一、杂类&lt;/h1&gt;
&lt;h2&gt;01 - int128 输出流自定义&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1806/submission/198413531&quot;&gt;2023-03-20&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;using i128 = __int128;

std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, i128 n) {
    std::string s;
    while (n) {
        s += &apos;0&apos; + n % 10;
        n /= 10;
    }
    std::reverse(s.begin(), s.end());
    return os &amp;#x3C;&amp;#x3C; s;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;02 - 常用库函数重载&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;using i64 = long long;
using i128 = __int128;

i64 ceilDiv(i64 n, i64 m) {
    if (n &gt;= 0) {
        return (n + m - 1) / m;
    } else {
        return n / m;
    }
}

i64 floorDiv(i64 n, i64 m) {
    if (n &gt;= 0) {
        return n / m;
    } else {
        return (n - m + 1) / m;
    }
}

template&amp;#x3C;class T&gt;
void chmax(T &amp;#x26;a, T b) {
    if (a &amp;#x3C; b) {
        a = b;
    }
}

i128 gcd(i128 a, i128 b) {
    return b ? gcd(b, a % b) : a;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h1&gt;二、图与网络&lt;/h1&gt;
&lt;h2&gt;01 - 强连通分量缩点（SCC）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1835/submission/210147209&quot;&gt;2023-06-18&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct SCC {
    int n;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; adj;
    std::vector&amp;#x3C;int&gt; stk;
    std::vector&amp;#x3C;int&gt; dfn, low, bel;
    int cur, cnt;

    SCC() {}
    SCC(int n) {
        init(n);
    }

    void init(int n) {
        this-&gt;n = n;
        adj.assign(n, {});
        dfn.assign(n, -1);
        low.resize(n);
        bel.assign(n, -1);
        stk.clear();
        cur = cnt = 0;
    }

    void addEdge(int u, int v) {
        adj[u].push_back(v);
    }

    void dfs(int x) {
        dfn[x] = low[x] = cur++;
        stk.push_back(x);

        for (auto y : adj[x]) {
            if (dfn[y] == -1) {
                dfs(y);
                low[x] = std::min(low[x], low[y]);
            } else if (bel[y] == -1) {
                low[x] = std::min(low[x], dfn[y]);
            }
        }

        if (dfn[x] == low[x]) {
            int y;
            do {
                y = stk.back();
                bel[y] = cnt;
                stk.pop_back();
            } while (y != x);
            cnt++;
        }
    }

    std::vector&amp;#x3C;int&gt; work() {
        for (int i = 0; i &amp;#x3C; n; i++) {
            if (dfn[i] == -1) {
                dfs(i);
            }
        }
        return bel;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;02 - 割边与割边缩点（EBCC）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/118/submission/205426518&quot;&gt;2023-05-11&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::set&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; E;

struct EBCC {
    int n;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; adj;
    std::vector&amp;#x3C;int&gt; stk;
    std::vector&amp;#x3C;int&gt; dfn, low, bel;
    int cur, cnt;

    EBCC() {}
    EBCC(int n) {
        init(n);
    }

    void init(int n) {
        this-&gt;n = n;
        adj.assign(n, {});
        dfn.assign(n, -1);
        low.resize(n);
        bel.assign(n, -1);
        stk.clear();
        cur = cnt = 0;
    }

    void addEdge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    void dfs(int x, int p) {
        dfn[x] = low[x] = cur++;
        stk.push_back(x);

        for (auto y : adj[x]) {
            if (y == p) {
                continue;
            }
            if (dfn[y] == -1) {
                E.emplace(x, y);
                dfs(y, x);
                low[x] = std::min(low[x], low[y]);
            } else if (bel[y] == -1 &amp;#x26;&amp;#x26; dfn[y] &amp;#x3C; dfn[x]) {
                E.emplace(x, y);
                low[x] = std::min(low[x], dfn[y]);
            }
        }

        if (dfn[x] == low[x]) {
            int y;
            do {
                y = stk.back();
                bel[y] = cnt;
                stk.pop_back();
            } while (y != x);
            cnt++;
        }
    }

    std::vector&amp;#x3C;int&gt; work() {
        dfs(0, -1);
        return bel;
    }

    struct Graph {
        int n;
        std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; edges;
        std::vector&amp;#x3C;int&gt; siz;
        std::vector&amp;#x3C;int&gt; cnte;
    };
    Graph compress() {
        Graph g;
        g.n = cnt;
        g.siz.resize(cnt);
        g.cnte.resize(cnt);
        for (int i = 0; i &amp;#x3C; n; i++) {
            g.siz[bel[i]]++;
            for (auto j : adj[i]) {
                if (bel[i] &amp;#x3C; bel[j]) {
                    g.edges.emplace_back(bel[i], bel[j]);
                } else if (i &amp;#x3C; j) {
                    g.cnte[bel[i]]++;
                }
            }
        }
        return g;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03 - 二分图最大权匹配（MaxAssignment 基于KM）【久远】&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/abc247/submissions/30867023&quot;&gt;2022-04-10&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
struct MaxAssignment {
    public:
        T solve(int nx, int ny, std::vector&amp;#x3C;std::vector&amp;#x3C;T&gt;&gt; a) {
            assert(0 &amp;#x3C;= nx &amp;#x26;&amp;#x26; nx &amp;#x3C;= ny);
            assert(int(a.size()) == nx);
            for (int i = 0; i &amp;#x3C; nx; ++i) {
                assert(int(a[i].size()) == ny);
                for (auto x : a[i])
                    assert(x &gt;= 0);
            }

            auto update = [&amp;#x26;](int x) {
                for (int y = 0; y &amp;#x3C; ny; ++y) {
                    if (lx[x] + ly[y] - a[x][y] &amp;#x3C; slack[y]) {
                        slack[y] = lx[x] + ly[y] - a[x][y];
                        slackx[y] = x;
                    }
                }
            };

            costs.resize(nx + 1);
            costs[0] = 0;
            lx.assign(nx, std::numeric_limits&amp;#x3C;T&gt;::max());
            ly.assign(ny, 0);
            xy.assign(nx, -1);
            yx.assign(ny, -1);
            slackx.resize(ny);
            for (int cur = 0; cur &amp;#x3C; nx; ++cur) {
                std::queue&amp;#x3C;int&gt; que;
                visx.assign(nx, false);
                visy.assign(ny, false);
                slack.assign(ny, std::numeric_limits&amp;#x3C;T&gt;::max());
                p.assign(nx, -1);

                for (int x = 0; x &amp;#x3C; nx; ++x) {
                    if (xy[x] == -1) {
                        que.push(x);
                        visx[x] = true;
                        update(x);
                    }
                }

                int ex, ey;
                bool found = false;
                while (!found) {
                    while (!que.empty() &amp;#x26;&amp;#x26; !found) {
                        auto x = que.front();
                        que.pop();
                        for (int y = 0; y &amp;#x3C; ny; ++y) {
                            if (a[x][y] == lx[x] + ly[y] &amp;#x26;&amp;#x26; !visy[y]) {
                                if (yx[y] == -1) {
                                    ex = x;
                                    ey = y;
                                    found = true;
                                    break;
                                }
                                que.push(yx[y]);
                                p[yx[y]] = x;
                                visy[y] = visx[yx[y]] = true;
                                update(yx[y]);
                            }
                        }
                    }
                    if (found)
                        break;

                    T delta = std::numeric_limits&amp;#x3C;T&gt;::max();
                    for (int y = 0; y &amp;#x3C; ny; ++y)
                        if (!visy[y])
                            delta = std::min(delta, slack[y]);
                    for (int x = 0; x &amp;#x3C; nx; ++x)
                        if (visx[x])
                            lx[x] -= delta;
                    for (int y = 0; y &amp;#x3C; ny; ++y) {
                        if (visy[y]) {
                            ly[y] += delta;
                        } else {
                            slack[y] -= delta;
                        }
                    }
                    for (int y = 0; y &amp;#x3C; ny; ++y) {
                        if (!visy[y] &amp;#x26;&amp;#x26; slack[y] == 0) {
                            if (yx[y] == -1) {
                                ex = slackx[y];
                                ey = y;
                                found = true;
                                break;
                            }
                            que.push(yx[y]);
                            p[yx[y]] = slackx[y];
                            visy[y] = visx[yx[y]] = true;
                            update(yx[y]);
                        }
                    }
                }

                costs[cur + 1] = costs[cur];
                for (int x = ex, y = ey, ty; x != -1; x = p[x], y = ty) {
                    costs[cur + 1] += a[x][y];
                    if (xy[x] != -1)
                        costs[cur + 1] -= a[x][xy[x]];
                    ty = xy[x];
                    xy[x] = y;
                    yx[y] = x;
                }
            }
            return costs[nx];
        }
        std::vector&amp;#x3C;int&gt; assignment() {
            return xy;
        }
        std::pair&amp;#x3C;std::vector&amp;#x3C;T&gt;, std::vector&amp;#x3C;T&gt;&gt; labels() {
            return std::make_pair(lx, ly);
        }
        std::vector&amp;#x3C;T&gt; weights() {
            return costs;
        }
    private:
        std::vector&amp;#x3C;T&gt; lx, ly, slack, costs;
        std::vector&amp;#x3C;int&gt; xy, yx, p, slackx;
        std::vector&amp;#x3C;bool&gt; visx, visy;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04 - 一般图最大匹配（Graph 带花树算法）【久远】&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1615/submission/140509278&quot;&gt;2021-12-24&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Graph {
    int n;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; e;
    Graph(int n) : n(n), e(n) {}
    void addEdge(int u, int v) {
        e[u].push_back(v);
        e[v].push_back(u);
    }
    std::vector&amp;#x3C;int&gt; findMatching() {
        std::vector&amp;#x3C;int&gt; match(n, -1), vis(n), link(n), f(n), dep(n);

        // disjoint set union
        auto find = [&amp;#x26;](int u) {
            while (f[u] != u)
                u = f[u] = f[f[u]];
            return u;
        };

        auto lca = [&amp;#x26;](int u, int v) {
            u = find(u);
            v = find(v);
            while (u != v) {
                if (dep[u] &amp;#x3C; dep[v])
                    std::swap(u, v);
                u = find(link[match[u]]);
            }
            return u;
        };

        std::queue&amp;#x3C;int&gt; que;
        auto blossom = [&amp;#x26;](int u, int v, int p) {
            while (find(u) != p) {
                link[u] = v;
                v = match[u];
                if (vis[v] == 0) {
                    vis[v] = 1;
                    que.push(v);
                }
                f[u] = f[v] = p;
                u = link[v];
            }
        };

        // find an augmenting path starting from u and augment (if exist)
        auto augment = [&amp;#x26;](int u) {

            while (!que.empty())
                que.pop();

            std::iota(f.begin(), f.end(), 0);

            // vis = 0 corresponds to inner vertices, vis = 1 corresponds to outer vertices
            std::fill(vis.begin(), vis.end(), -1);

            que.push(u);
            vis[u] = 1;
            dep[u] = 0;

            while (!que.empty()){
                int u = que.front();
                que.pop();
                for (auto v : e[u]) {
                    if (vis[v] == -1) {

                        vis[v] = 0;
                        link[v] = u;
                        dep[v] = dep[u] + 1;

                        // found an augmenting path
                        if (match[v] == -1) {
                            for (int x = v, y = u, temp; y != -1; x = temp, y = x == -1 ? -1 : link[x]) {
                                temp = match[y];
                                match[x] = y;
                                match[y] = x;
                            }
                            return;
                        }

                        vis[match[v]] = 1;
                        dep[match[v]] = dep[u] + 2;
                        que.push(match[v]);

                    } else if (vis[v] == 1 &amp;#x26;&amp;#x26; find(v) != find(u)) {
                        // found a blossom
                        int p = lca(u, v);
                        blossom(u, v, p);
                        blossom(v, u, p);
                    }
                }
            }

        };

        // find a maximal matching greedily (decrease constant)
        auto greedy = [&amp;#x26;]() {

            for (int u = 0; u &amp;#x3C; n; ++u) {
                if (match[u] != -1)
                    continue;
                for (auto v : e[u]) {
                    if (match[v] == -1) {
                        match[u] = v;
                        match[v] = u;
                        break;
                    }
                }
            }
        };

        greedy();

        for (int u = 0; u &amp;#x3C; n; ++u)
            if (match[u] == -1)
                augment(u);

        return match;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;05 - TwoSat（2-Sat）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/arc161/submissions/46031530&quot;&gt;2023-09-29&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct TwoSat {
    int n;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; e;
    std::vector&amp;#x3C;bool&gt; ans;
    TwoSat(int n) : n(n), e(2 * n), ans(n) {}
    void addClause(int u, bool f, int v, bool g) {
        e[2 * u + !f].push_back(2 * v + g);
        e[2 * v + !g].push_back(2 * u + f);
    }
    bool satisfiable() {
        std::vector&amp;#x3C;int&gt; id(2 * n, -1), dfn(2 * n, -1), low(2 * n, -1);
        std::vector&amp;#x3C;int&gt; stk;
        int now = 0, cnt = 0;
        std::function&amp;#x3C;void(int)&gt; tarjan = [&amp;#x26;](int u) {
            stk.push_back(u);
            dfn[u] = low[u] = now++;
            for (auto v : e[u]) {
                if (dfn[v] == -1) {
                    tarjan(v);
                    low[u] = std::min(low[u], low[v]);
                } else if (id[v] == -1) {
                    low[u] = std::min(low[u], dfn[v]);
                }
            }
            if (dfn[u] == low[u]) {
                int v;
                do {
                    v = stk.back();
                    stk.pop_back();
                    id[v] = cnt;
                } while (v != u);
                ++cnt;
            }
        };
        for (int i = 0; i &amp;#x3C; 2 * n; ++i) if (dfn[i] == -1) tarjan(i);
        for (int i = 0; i &amp;#x3C; n; ++i) {
            if (id[2 * i] == id[2 * i + 1]) return false;
            ans[i] = id[2 * i] &gt; id[2 * i + 1];
        }
        return true;
    }
    std::vector&amp;#x3C;bool&gt; answer() { return ans; }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06A - 最大流（Flow 旧版其一，整数应用）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1717/submission/170688062&quot;&gt;2022-09-03&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
struct Flow {
    const int n;
    struct Edge {
        int to;
        T cap;
        Edge(int to, T cap) : to(to), cap(cap) {}
    };
    std::vector&amp;#x3C;Edge&gt; e;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; g;
    std::vector&amp;#x3C;int&gt; cur, h;
    Flow(int n) : n(n), g(n) {}

    bool bfs(int s, int t) {
        h.assign(n, -1);
        std::queue&amp;#x3C;int&gt; que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            const int u = que.front();
            que.pop();
            for (int i : g[u]) {
                auto [v, c] = e[i];
                if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t) {
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return false;
    }

    T dfs(int u, int t, T f) {
        if (u == t) {
            return f;
        }
        auto r = f;
        for (int &amp;#x26;i = cur[u]; i &amp;#x3C; int(g[u].size()); ++i) {
            const int j = g[u][i];
            auto [v, c] = e[j];
            if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == h[u] + 1) {
                auto a = dfs(v, t, std::min(r, c));
                e[j].cap -= a;
                e[j ^ 1].cap += a;
                r -= a;
                if (r == 0) {
                    return f;
                }
            }
        }
        return f - r;
    }
    void addEdge(int u, int v, T c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    T maxFlow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, std::numeric_limits&amp;#x3C;T&gt;::max());
        }
        return ans;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06B - 最大流（Flow 旧版其二，浮点数应用）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104288/submission/201412765&quot;&gt;2022-04-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
struct Flow {
    const int n;
    struct Edge {
        int to;
        T cap;
        Edge(int to, T cap) : to(to), cap(cap) {}
    };
    std::vector&amp;#x3C;Edge&gt; e;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; g;
    std::vector&amp;#x3C;int&gt; cur, h;
    Flow(int n) : n(n), g(n) {}

    bool bfs(int s, int t) {
        h.assign(n, -1);
        std::queue&amp;#x3C;int&gt; que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            const int u = que.front();
            que.pop();
            for (int i : g[u]) {
                auto [v, c] = e[i];
                if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t) {
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return false;
    }

    T dfs(int u, int t, T f) {
        if (u == t) {
            return f;
        }
        auto r = f;
        double res = 0;
        for (int &amp;#x26;i = cur[u]; i &amp;#x3C; int(g[u].size()); ++i) {
            const int j = g[u][i];
            auto [v, c] = e[j];
            if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == h[u] + 1) {
                auto a = dfs(v, t, std::min(r, c));
                res += a;
                e[j].cap -= a;
                e[j ^ 1].cap += a;
                r -= a;
                if (r == 0) {
                    return f;
                }
            }
        }
        return res;
    }
    void addEdge(int u, int v, T c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    T maxFlow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, 1E100);
        }
        return ans;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06C - 最大流（MaxFlow 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=62915815&quot;&gt;2023-07-21&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;constexpr int inf = 1E9;
template&amp;#x3C;class T&gt;
struct MaxFlow {
    struct _Edge {
        int to;
        T cap;
        _Edge(int to, T cap) : to(to), cap(cap) {}
    };

    int n;
    std::vector&amp;#x3C;_Edge&gt; e;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; g;
    std::vector&amp;#x3C;int&gt; cur, h;

    MaxFlow() {}
    MaxFlow(int n) {
        init(n);
    }

    void init(int n) {
        this-&gt;n = n;
        e.clear();
        g.assign(n, {});
        cur.resize(n);
        h.resize(n);
    }

    bool bfs(int s, int t) {
        h.assign(n, -1);
        std::queue&amp;#x3C;int&gt; que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            const int u = que.front();
            que.pop();
            for (int i : g[u]) {
                auto [v, c] = e[i];
                if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t) {
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return false;
    }

    T dfs(int u, int t, T f) {
        if (u == t) {
            return f;
        }
        auto r = f;
        for (int &amp;#x26;i = cur[u]; i &amp;#x3C; int(g[u].size()); ++i) {
            const int j = g[u][i];
            auto [v, c] = e[j];
            if (c &gt; 0 &amp;#x26;&amp;#x26; h[v] == h[u] + 1) {
                auto a = dfs(v, t, std::min(r, c));
                e[j].cap -= a;
                e[j ^ 1].cap += a;
                r -= a;
                if (r == 0) {
                    return f;
                }
            }
        }
        return f - r;
    }
    void addEdge(int u, int v, T c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    T flow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, std::numeric_limits&amp;#x3C;T&gt;::max());
        }
        return ans;
    }

    std::vector&amp;#x3C;bool&gt; minCut() {
        std::vector&amp;#x3C;bool&gt; c(n);
        for (int i = 0; i &amp;#x3C; n; i++) {
            c[i] = (h[i] != -1);
        }
        return c;
    }

    struct Edge {
        int from;
        int to;
        T cap;
        T flow;
    };
    std::vector&amp;#x3C;Edge&gt; edges() {
        std::vector&amp;#x3C;Edge&gt; a;
        for (int i = 0; i &amp;#x3C; e.size(); i += 2) {
            Edge x;
            x.from = e[i + 1].to;
            x.to = e[i].to;
            x.cap = e[i].cap + e[i + 1].cap;
            x.flow = e[i + 1].cap;
            a.push_back(x);
        }
        return a;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;07A - 费用流（MCFGraph 最小费用可行流）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1766/submission/184974697&quot;&gt;2022-12-12&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct MCFGraph {
    struct Edge {
        int v, c, f;
        Edge(int v, int c, int f) : v(v), c(c), f(f) {}
    };
    const int n;
    std::vector&amp;#x3C;Edge&gt; e;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; g;
    std::vector&amp;#x3C;i64&gt; h, dis;
    std::vector&amp;#x3C;int&gt; pre;
    bool dijkstra(int s, int t) {
        dis.assign(n, std::numeric_limits&amp;#x3C;i64&gt;::max());
        pre.assign(n, -1);
        std::priority_queue&amp;#x3C;std::pair&amp;#x3C;i64, int&gt;, std::vector&amp;#x3C;std::pair&amp;#x3C;i64, int&gt;&gt;, std::greater&amp;#x3C;std::pair&amp;#x3C;i64, int&gt;&gt;&gt; que;
        dis[s] = 0;
        que.emplace(0, s);
        while (!que.empty()) {
            i64 d = que.top().first;
            int u = que.top().second;
            que.pop();
            if (dis[u] &amp;#x3C; d) continue;
            for (int i : g[u]) {
                int v = e[i].v;
                int c = e[i].c;
                int f = e[i].f;
                if (c &gt; 0 &amp;#x26;&amp;#x26; dis[v] &gt; d + h[u] - h[v] + f) {
                    dis[v] = d + h[u] - h[v] + f;
                    pre[v] = i;
                    que.emplace(dis[v], v);
                }
            }
        }
        return dis[t] != std::numeric_limits&amp;#x3C;i64&gt;::max();
    }
    MCFGraph(int n) : n(n), g(n) {}
    void addEdge(int u, int v, int c, int f) {
        if (f &amp;#x3C; 0) {
            g[u].push_back(e.size());
            e.emplace_back(v, 0, f);
            g[v].push_back(e.size());
            e.emplace_back(u, c, -f);
        } else {
            g[u].push_back(e.size());
            e.emplace_back(v, c, f);
            g[v].push_back(e.size());
            e.emplace_back(u, 0, -f);
        }
    }
    std::pair&amp;#x3C;int, i64&gt; flow(int s, int t) {
        int flow = 0;
        i64 cost = 0;
        h.assign(n, 0);
        while (dijkstra(s, t)) {
            for (int i = 0; i &amp;#x3C; n; ++i) h[i] += dis[i];
            int aug = std::numeric_limits&amp;#x3C;int&gt;::max();
            for (int i = t; i != s; i = e[pre[i] ^ 1].v) aug = std::min(aug, e[pre[i]].c);
            for (int i = t; i != s; i = e[pre[i] ^ 1].v) {
                e[pre[i]].c -= aug;
                e[pre[i] ^ 1].c += aug;
            }
            flow += aug;
            cost += i64(aug) * h[t];
        }
        return std::make_pair(flow, cost);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;07B - 费用流（MCFGraph 最小费用最大流）&lt;/h2&gt;
&lt;p&gt;代码同上，但是需要注释掉建边限制。以下为参考：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;void addEdge(int u, int v, int c, int f) { // 可行流
    if (f &amp;#x3C; 0) {
        g[u].push_back(e.size());
        e.emplace_back(v, 0, f);
        g[v].push_back(e.size());
        e.emplace_back(u, c, -f);
    } else {
        g[u].push_back(e.size());
        e.emplace_back(v, c, f);
        g[v].push_back(e.size());
        e.emplace_back(u, 0, -f);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-c&quot;&gt;void addEdge(int u, int v, int c, int f) { // 最大流
    g[u].push_back(e.size());
    e.emplace_back(v, c, f);
    g[v].push_back(e.size());
    e.emplace_back(u, 0, -f);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;08 - 树链剖分（HLD）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1863/submission/221214363&quot;&gt;2023-08-31&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct HLD {
    int n;
    std::vector&amp;#x3C;int&gt; siz, top, dep, parent, in, out, seq;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; adj;
    int cur;

    HLD() {}
    HLD(int n) {
        init(n);
    }
    void init(int n) {
        this-&gt;n = n;
        siz.resize(n);
        top.resize(n);
        dep.resize(n);
        parent.resize(n);
        in.resize(n);
        out.resize(n);
        seq.resize(n);
        cur = 0;
        adj.assign(n, {});
    }
    void addEdge(int u, int v) {
        adj[u].push_back(v);
        adj[v].push_back(u);
    }
    void work(int root = 0) {
        top[root] = root;
        dep[root] = 0;
        parent[root] = -1;
        dfs1(root);
        dfs2(root);
    }
    void dfs1(int u) {
        if (parent[u] != -1) {
            adj[u].erase(std::find(adj[u].begin(), adj[u].end(), parent[u]));
        }

        siz[u] = 1;
        for (auto &amp;#x26;v : adj[u]) {
            parent[v] = u;
            dep[v] = dep[u] + 1;
            dfs1(v);
            siz[u] += siz[v];
            if (siz[v] &gt; siz[adj[u][0]]) {
                std::swap(v, adj[u][0]);
            }
        }
    }
    void dfs2(int u) {
        in[u] = cur++;
        seq[in[u]] = u;
        for (auto v : adj[u]) {
            top[v] = v == adj[u][0] ? top[u] : v;
            dfs2(v);
        }
        out[u] = cur;
    }
    int lca(int u, int v) {
        while (top[u] != top[v]) {
            if (dep[top[u]] &gt; dep[top[v]]) {
                u = parent[top[u]];
            } else {
                v = parent[top[v]];
            }
        }
        return dep[u] &amp;#x3C; dep[v] ? u : v;
    }

    int dist(int u, int v) {
        return dep[u] + dep[v] - 2 * dep[lca(u, v)];
    }

    int jump(int u, int k) {
        if (dep[u] &amp;#x3C; k) {
            return -1;
        }

        int d = dep[u] - k;

        while (dep[top[u]] &gt; d) {
            u = parent[top[u]];
        }

        return seq[in[u] - dep[u] + d];
    }

    bool isAncester(int u, int v) {
        return in[u] &amp;#x3C;= in[v] &amp;#x26;&amp;#x26; in[v] &amp;#x3C; out[u];
    }

    int rootedParent(int u, int v) {
        std::swap(u, v);
        if (u == v) {
            return u;
        }
        if (!isAncester(u, v)) {
            return parent[u];
        }
        auto it = std::upper_bound(adj[u].begin(), adj[u].end(), v, [&amp;#x26;](int x, int y) {
            return in[x] &amp;#x3C; in[y];
        }) - 1;
        return *it;
    }

    int rootedSize(int u, int v) {
        if (u == v) {
            return n;
        }
        if (!isAncester(v, u)) {
            return siz[v];
        }
        return n - siz[rootedParent(u, v)];
    }

    int rootedLca(int a, int b, int c) {
        return lca(a, b) ^ lca(b, c) ^ lca(c, a);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h1&gt;三、数论、几何、多项式&lt;/h1&gt;
&lt;h2&gt;01 - 快速幂&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/tenka1-2017/submissions/46411797&quot;&gt;2023-10-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;int power(int a, i64 b, int p) {
    int res = 1;
    for (; b; b /= 2, a = 1LL * a * a % p) {
        if (b % 2) {
            res = 1LL * res * a % p;
        }
    }
    return res;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;02 - 欧拉筛&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104479/submission/220987267&quot;&gt;2023-08-29&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;int&gt; minp, primes;

void sieve(int n) {
    minp.assign(n + 1, 0);
    primes.clear();

    for (int i = 2; i &amp;#x3C;= n; i++) {
        if (minp[i] == 0) {
            minp[i] = i;
            primes.push_back(i);
        }

        for (auto p : primes) {
            if (i * p &gt; n) {
                break;
            }
            minp[i * p] = p;
            if (p == minp[i]) {
                break;
            }
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03 - 莫比乌斯函数筛（莫比乌斯函数/反演）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/tupc2022/submissions/39391116&quot;&gt;2023-03-04&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::unordered_map&amp;#x3C;int, Z&gt; fMu;

constexpr int N = 1E7;
std::vector&amp;#x3C;int&gt; minp, primes;
std::vector&amp;#x3C;Z&gt; mu;

void sieve(int n) {
    minp.assign(n + 1, 0);
    mu.resize(n);
    primes.clear();

    mu[1] = 1;
    for (int i = 2; i &amp;#x3C;= n; i++) {
        if (minp[i] == 0) {
            mu[i] = -1;
            minp[i] = i;
            primes.push_back(i);
        }

        for (auto p : primes) {
            if (i * p &gt; n) {
                break;
            }
            minp[i * p] = p;
            if (p == minp[i]) {
                break;
            }
            mu[i * p] = -mu[i];
        }
    }

    for (int i = 1; i &amp;#x3C;= n; i++) {
        mu[i] += mu[i - 1];
    }
}


Z sumMu(int n) {
    if (n &amp;#x3C;= N) {
        return mu[n];
    }
    if (fMu.count(n)) {
        return fMu[n];
    }
    if (n == 0) {
        return 0;
    }
    Z ans = 1;
    for (int l = 2, r; l &amp;#x3C;= n; l = r + 1) {
        r = n / (n / l);
        ans -= (r - l + 1) * sumMu(n / l);
    }
    return ans;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    sieve(N);

    int L, R;
    std::cin &gt;&gt; L &gt;&gt; R;
    L -= 1;

    Z ans = 0;
    for (int l = 1, r; l &amp;#x3C;= R; l = r + 1) {
        r = R / (R / l);
        if (l &amp;#x3C;= L) {
            r = std::min(r, L / (L / l));
        }

        ans += (power(Z(2), R / l - L / l) - 1) * (sumMu(r) - sumMu(l - 1));
    }

    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; &quot;\n&quot;;

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04 - 求解单个数的欧拉函数&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/tenka1-2017/submissions/46411797&quot;&gt;2023-10-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;int phi(int n) {
    int res = n;
    for (int i = 2; i * i &amp;#x3C;= n; i++) {
        if (n % i == 0) {
            while (n % i == 0) {
                n /= i;
            }
            res = res / i * (i - 1);
        }
    }
    if (n &gt; 1) {
        res = res / n * (n - 1);
    }
    return res;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;05 - 扩展欧几里得（exGCD）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/tenka1-2017/submissions/46411797&quot;&gt;2023-10-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;int exgcd(int a, int b, int &amp;#x26;x, int &amp;#x26;y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    int g = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return g;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06 - 组合数（Comb+MInt &amp;#x26; MLong）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1864/submission/220584872&quot;&gt;2023-08-26&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Comb {
    int n;
    std::vector&amp;#x3C;Z&gt; _fac;
    std::vector&amp;#x3C;Z&gt; _invfac;
    std::vector&amp;#x3C;Z&gt; _inv;

    Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}
    Comb(int n) : Comb() {
        init(n);
    }

    void init(int m) {
        m = std::min(m, Z::getMod() - 1);
        if (m &amp;#x3C;= n) return;
        _fac.resize(m + 1);
        _invfac.resize(m + 1);
        _inv.resize(m + 1);

        for (int i = n + 1; i &amp;#x3C;= m; i++) {
            _fac[i] = _fac[i - 1] * i;
        }
        _invfac[m] = _fac[m].inv();
        for (int i = m; i &gt; n; i--) {
            _invfac[i - 1] = _invfac[i] * i;
            _inv[i] = _invfac[i] * _fac[i - 1];
        }
        n = m;
    }

    Z fac(int m) {
        if (m &gt; n) init(2 * m);
        return _fac[m];
    }
    Z invfac(int m) {
        if (m &gt; n) init(2 * m);
        return _invfac[m];
    }
    Z inv(int m) {
        if (m &gt; n) init(2 * m);
        return _inv[m];
    }
    Z binom(int n, int m) {
        if (n &amp;#x3C; m || m &amp;#x3C; 0) return 0;
        return fac(n) * invfac(m) * invfac(n - m);
    }
} comb;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;07 - 二项式（Binomial 任意模数计算）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/896/submission/219861532&quot;&gt;2023-08-22&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; factorize(int n) {
    std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; factors;
    for (int i = 2; static_cast&amp;#x3C;long long&gt;(i) * i &amp;#x3C;= n; i++) {
        if (n % i == 0) {
            int t = 0;
            for (; n % i == 0; n /= i)
                ++t;
            factors.emplace_back(i, t);
        }
    }
    if (n &gt; 1)
        factors.emplace_back(n, 1);
    return factors;
}
constexpr int power(int base, i64 exp) {
    int res = 1;
    for (; exp &gt; 0; base *= base, exp /= 2) {
        if (exp % 2 == 1) {
            res *= base;
        }
    }
    return res;
}
constexpr int power(int base, i64 exp, int mod) {
    int res = 1 % mod;
    for (; exp &gt; 0; base = 1LL * base * base % mod, exp /= 2) {
        if (exp % 2 == 1) {
            res = 1LL * res * base % mod;
        }
    }
    return res;
}
int inverse(int a, int m) {
    int g = m, r = a, x = 0, y = 1;
    while (r != 0) {
        int q = g / r;
        g %= r;
        std::swap(g, r);
        x -= q * y;
        std::swap(x, y);
    }
    return x &amp;#x3C; 0 ? x + m : x;
}
int solveModuloEquations(const std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; &amp;#x26;e) {
    int m = 1;
    for (std::size_t i = 0; i &amp;#x3C; e.size(); i++) {
        m *= e[i].first;
    }
    int res = 0;
    for (std::size_t i = 0; i &amp;#x3C; e.size(); i++) {
        int p = e[i].first;
        res = (res + 1LL * e[i].second * (m / p) * inverse(m / p, p)) % m;
    }
    return res;
}
constexpr int N = 1E5;
class Binomial {
    const int mod;
private:
    const std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; factors;
    std::vector&amp;#x3C;int&gt; pk;
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt;&gt; prod;
    static constexpr i64 exponent(i64 n, int p) {
        i64 res = 0;
        for (n /= p; n &gt; 0; n /= p) {
            res += n;
        }
        return res;
    }
    int product(i64 n, std::size_t i) {
        int res = 1;
        int p = factors[i].first;
        for (; n &gt; 0; n /= p) {
            res = 1LL * res * power(prod[i].back(), n / pk[i], pk[i]) % pk[i] * prod[i][n % pk[i]] % pk[i];
        }
        return res;
    }
public:
    Binomial(int mod) : mod(mod), factors(factorize(mod)) {
        pk.resize(factors.size());
        prod.resize(factors.size());
        for (std::size_t i = 0; i &amp;#x3C; factors.size(); i++) {
            int p = factors[i].first;
            int k = factors[i].second;
            pk[i] = power(p, k);
            prod[i].resize(std::min(N + 1, pk[i]));
            prod[i][0] = 1;
            for (int j = 1; j &amp;#x3C; prod[i].size(); j++) {
                if (j % p == 0) {
                    prod[i][j] = prod[i][j - 1];
                } else {
                    prod[i][j] = 1LL * prod[i][j - 1] * j % pk[i];
                }
            }
        }
    }
    int operator()(i64 n, i64 m) {
        if (n &amp;#x3C; m || m &amp;#x3C; 0) {
            return 0;
        }
        std::vector&amp;#x3C;std::pair&amp;#x3C;int, int&gt;&gt; ans(factors.size());
        for (int i = 0; i &amp;#x3C; factors.size(); i++) {
            int p = factors[i].first;
            int k = factors[i].second;
            int e = exponent(n, p) - exponent(m, p) - exponent(n - m, p);
            if (e &gt;= k) {
                ans[i] = std::make_pair(pk[i], 0);
            } else {
                int pn = product(n, i);
                int pm = product(m, i);
                int pd = product(n - m, i);
                int res = 1LL * pn * inverse(pm, pk[i]) % pk[i] * inverse(pd, pk[i]) % pk[i] * power(p, e) % pk[i];
                ans[i] = std::make_pair(pk[i], res);
            }
        }
        return solveModuloEquations(ans);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;08 - 素数测试与因式分解（Miller-Rabin &amp;#x26; Pollard-Rho）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104354/submission/206130894&quot;&gt;2023-05-16&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;i64 mul(i64 a, i64 b, i64 m) {
    return static_cast&amp;#x3C;__int128&gt;(a) * b % m;
}
i64 power(i64 a, i64 b, i64 m) {
    i64 res = 1 % m;
    for (; b; b &gt;&gt;= 1, a = mul(a, a, m))
        if (b &amp;#x26; 1)
            res = mul(res, a, m);
    return res;
}
bool isprime(i64 n) {
    if (n &amp;#x3C; 2)
        return false;
    static constexpr int A[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
    int s = __builtin_ctzll(n - 1);
    i64 d = (n - 1) &gt;&gt; s;
    for (auto a : A) {
        if (a == n)
            return true;
        i64 x = power(a, d, n);
        if (x == 1 || x == n - 1)
            continue;
        bool ok = false;
        for (int i = 0; i &amp;#x3C; s - 1; ++i) {
            x = mul(x, x, n);
            if (x == n - 1) {
                ok = true;
                break;
            }
        }
        if (!ok)
            return false;
    }
    return true;
}
std::vector&amp;#x3C;i64&gt; factorize(i64 n) {
    std::vector&amp;#x3C;i64&gt; p;
    std::function&amp;#x3C;void(i64)&gt; f = [&amp;#x26;](i64 n) {
        if (n &amp;#x3C;= 10000) {
            for (int i = 2; i * i &amp;#x3C;= n; ++i)
                for (; n % i == 0; n /= i)
                    p.push_back(i);
            if (n &gt; 1)
                p.push_back(n);
            return;
        }
        if (isprime(n)) {
            p.push_back(n);
            return;
        }
        auto g = [&amp;#x26;](i64 x) {
            return (mul(x, x, n) + 1) % n;
        };
        i64 x0 = 2;
        while (true) {
            i64 x = x0;
            i64 y = x0;
            i64 d = 1;
            i64 power = 1, lam = 0;
            i64 v = 1;
            while (d == 1) {
                y = g(y);
                ++lam;
                v = mul(v, std::abs(x - y), n);
                if (lam % 127 == 0) {
                    d = std::gcd(v, n);
                    v = 1;
                }
                if (power == lam) {
                    x = y;
                    power *= 2;
                    lam = 0;
                    d = std::gcd(v, n);
                    v = 1;
                }
            }
            if (d != n) {
                f(d);
                f(n / d);
                return;
            }
            ++x0;
        }
    };
    f(n);
    std::sort(p.begin(), p.end());
    return p;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;09 - 平面几何&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=62808640&quot;&gt;2023-07-17&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
struct Point {
    T x;
    T y;
    Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {}

    template&amp;#x3C;class U&gt;
    operator Point&amp;#x3C;U&gt;() {
        return Point&amp;#x3C;U&gt;(U(x), U(y));
    }
    Point &amp;#x26;operator+=(Point p) &amp;#x26; {
        x += p.x;
        y += p.y;
        return *this;
    }
    Point &amp;#x26;operator-=(Point p) &amp;#x26; {
        x -= p.x;
        y -= p.y;
        return *this;
    }
    Point &amp;#x26;operator*=(T v) &amp;#x26; {
        x *= v;
        y *= v;
        return *this;
    }
    Point operator-() const {
        return Point(-x, -y);
    }
    friend Point operator+(Point a, Point b) {
        return a += b;
    }
    friend Point operator-(Point a, Point b) {
        return a -= b;
    }
    friend Point operator*(Point a, T b) {
        return a *= b;
    }
    friend Point operator*(T a, Point b) {
        return b *= a;
    }
    friend bool operator==(Point a, Point b) {
        return a.x == b.x &amp;#x26;&amp;#x26; a.y == b.y;
    }
    friend std::istream &amp;#x26;operator&gt;&gt;(std::istream &amp;#x26;is, Point &amp;#x26;p) {
        return is &gt;&gt; p.x &gt;&gt; p.y;
    }
    friend std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, Point p) {
        return os &amp;#x3C;&amp;#x3C; &quot;(&quot; &amp;#x3C;&amp;#x3C; p.x &amp;#x3C;&amp;#x3C; &quot;, &quot; &amp;#x3C;&amp;#x3C; p.y &amp;#x3C;&amp;#x3C; &quot;)&quot;;
    }
};

template&amp;#x3C;class T&gt;
T dot(Point&amp;#x3C;T&gt; a, Point&amp;#x3C;T&gt; b) {
    return a.x * b.x + a.y * b.y;
}

template&amp;#x3C;class T&gt;
T cross(Point&amp;#x3C;T&gt; a, Point&amp;#x3C;T&gt; b) {
    return a.x * b.y - a.y * b.x;
}

template&amp;#x3C;class T&gt;
T square(Point&amp;#x3C;T&gt; p) {
    return dot(p, p);
}

template&amp;#x3C;class T&gt;
double length(Point&amp;#x3C;T&gt; p) {
    return std::sqrt(double(square(p)));
}

long double length(Point&amp;#x3C;long double&gt; p) {
    return std::sqrt(square(p));
}

template&amp;#x3C;class T&gt;
struct Line {
    Point&amp;#x3C;T&gt; a;
    Point&amp;#x3C;T&gt; b;
    Line(Point&amp;#x3C;T&gt; a_ = Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt; b_ = Point&amp;#x3C;T&gt;()) : a(a_), b(b_) {}
};

template&amp;#x3C;class T&gt;
Point&amp;#x3C;T&gt; rotate(Point&amp;#x3C;T&gt; a) {
    return Point(-a.y, a.x);
}

template&amp;#x3C;class T&gt;
int sgn(Point&amp;#x3C;T&gt; a) {
    return a.y &gt; 0 || (a.y == 0 &amp;#x26;&amp;#x26; a.x &gt; 0) ? 1 : -1;
}

template&amp;#x3C;class T&gt;
bool pointOnLineLeft(Point&amp;#x3C;T&gt; p, Line&amp;#x3C;T&gt; l) {
    return cross(l.b - l.a, p - l.a) &gt; 0;
}

template&amp;#x3C;class T&gt;
Point&amp;#x3C;T&gt; lineIntersection(Line&amp;#x3C;T&gt; l1, Line&amp;#x3C;T&gt; l2) {
    return l1.a + (l1.b - l1.a) * (cross(l2.b - l2.a, l1.a - l2.a) / cross(l2.b - l2.a, l1.a - l1.b));
}

template&amp;#x3C;class T&gt;
bool pointOnSegment(Point&amp;#x3C;T&gt; p, Line&amp;#x3C;T&gt; l) {
    return cross(p - l.a, l.b - l.a) == 0 &amp;#x26;&amp;#x26; std::min(l.a.x, l.b.x) &amp;#x3C;= p.x &amp;#x26;&amp;#x26; p.x &amp;#x3C;= std::max(l.a.x, l.b.x)
    &amp;#x26;&amp;#x26; std::min(l.a.y, l.b.y) &amp;#x3C;= p.y &amp;#x26;&amp;#x26; p.y &amp;#x3C;= std::max(l.a.y, l.b.y);
}

template&amp;#x3C;class T&gt;
bool pointInPolygon(Point&amp;#x3C;T&gt; a, std::vector&amp;#x3C;Point&amp;#x3C;T&gt;&gt; p) {
    int n = p.size();
    for (int i = 0; i &amp;#x3C; n; i++) {
        if (pointOnSegment(a, Line(p[i], p[(i + 1) % n]))) {
            return true;
        }
    }

    int t = 0;
    for (int i = 0; i &amp;#x3C; n; i++) {
        auto u = p[i];
        auto v = p[(i + 1) % n];
        if (u.x &amp;#x3C; a.x &amp;#x26;&amp;#x26; v.x &gt;= a.x &amp;#x26;&amp;#x26; pointOnLineLeft(a, Line(v, u))) {
            t ^= 1;
        }
        if (u.x &gt;= a.x &amp;#x26;&amp;#x26; v.x &amp;#x3C; a.x &amp;#x26;&amp;#x26; pointOnLineLeft(a, Line(u, v))) {
            t ^= 1;
        }
    }

    return t == 1;
}

// 0 : not intersect
// 1 : strictly intersect
// 2 : overlap
// 3 : intersect at endpoint
template&amp;#x3C;class T&gt;
std::tuple&amp;#x3C;int, Point&amp;#x3C;T&gt;, Point&amp;#x3C;T&gt;&gt; segmentIntersection(Line&amp;#x3C;T&gt; l1, Line&amp;#x3C;T&gt; l2) {
    if (std::max(l1.a.x, l1.b.x) &amp;#x3C; std::min(l2.a.x, l2.b.x)) {
        return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
    }
    if (std::min(l1.a.x, l1.b.x) &gt; std::max(l2.a.x, l2.b.x)) {
        return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
    }
    if (std::max(l1.a.y, l1.b.y) &amp;#x3C; std::min(l2.a.y, l2.b.y)) {
        return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
    }
    if (std::min(l1.a.y, l1.b.y) &gt; std::max(l2.a.y, l2.b.y)) {
        return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
    }
    if (cross(l1.b - l1.a, l2.b - l2.a) == 0) {
        if (cross(l1.b - l1.a, l2.a - l1.a) != 0) {
            return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
        } else {
            auto maxx1 = std::max(l1.a.x, l1.b.x);
            auto minx1 = std::min(l1.a.x, l1.b.x);
            auto maxy1 = std::max(l1.a.y, l1.b.y);
            auto miny1 = std::min(l1.a.y, l1.b.y);
            auto maxx2 = std::max(l2.a.x, l2.b.x);
            auto minx2 = std::min(l2.a.x, l2.b.x);
            auto maxy2 = std::max(l2.a.y, l2.b.y);
            auto miny2 = std::min(l2.a.y, l2.b.y);
            Point&amp;#x3C;T&gt; p1(std::max(minx1, minx2), std::max(miny1, miny2));
            Point&amp;#x3C;T&gt; p2(std::min(maxx1, maxx2), std::min(maxy1, maxy2));
            if (!pointOnSegment(p1, l1)) {
                std::swap(p1.y, p2.y);
            }
            if (p1 == p2) {
                return {3, p1, p2};
            } else {
                return {2, p1, p2};
            }
        }
    }
    auto cp1 = cross(l2.a - l1.a, l2.b - l1.a);
    auto cp2 = cross(l2.a - l1.b, l2.b - l1.b);
    auto cp3 = cross(l1.a - l2.a, l1.b - l2.a);
    auto cp4 = cross(l1.a - l2.b, l1.b - l2.b);

    if ((cp1 &gt; 0 &amp;#x26;&amp;#x26; cp2 &gt; 0) || (cp1 &amp;#x3C; 0 &amp;#x26;&amp;#x26; cp2 &amp;#x3C; 0) || (cp3 &gt; 0 &amp;#x26;&amp;#x26; cp4 &gt; 0) || (cp3 &amp;#x3C; 0 &amp;#x26;&amp;#x26; cp4 &amp;#x3C; 0)) {
        return {0, Point&amp;#x3C;T&gt;(), Point&amp;#x3C;T&gt;()};
    }

    Point p = lineIntersection(l1, l2);
    if (cp1 != 0 &amp;#x26;&amp;#x26; cp2 != 0 &amp;#x26;&amp;#x26; cp3 != 0 &amp;#x26;&amp;#x26; cp4 != 0) {
        return {1, p, p};
    } else {
        return {3, p, p};
    }
}

template&amp;#x3C;class T&gt;
bool segmentInPolygon(Line&amp;#x3C;T&gt; l, std::vector&amp;#x3C;Point&amp;#x3C;T&gt;&gt; p) {
    int n = p.size();
    if (!pointInPolygon(l.a, p)) {
        return false;
    }
    if (!pointInPolygon(l.b, p)) {
        return false;
    }
    for (int i = 0; i &amp;#x3C; n; i++) {
        auto u = p[i];
        auto v = p[(i + 1) % n];
        auto w = p[(i + 2) % n];
        auto [t, p1, p2] = segmentIntersection(l, Line(u, v));

        if (t == 1) {
            return false;
        }
        if (t == 0) {
            continue;
        }
        if (t == 2) {
            if (pointOnSegment(v, l) &amp;#x26;&amp;#x26; v != l.a &amp;#x26;&amp;#x26; v != l.b) {
                if (cross(v - u, w - v) &gt; 0) {
                    return false;
                }
            }
        } else {
            if (p1 != u &amp;#x26;&amp;#x26; p1 != v) {
                if (pointOnLineLeft(l.a, Line(v, u))
                    || pointOnLineLeft(l.b, Line(v, u))) {
                    return false;
                }
            } else if (p1 == v) {
                if (l.a == v) {
                    if (pointOnLineLeft(u, l)) {
                        if (pointOnLineLeft(w, l)
                            &amp;#x26;&amp;#x26; pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    } else {
                        if (pointOnLineLeft(w, l)
                            || pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    }
                } else if (l.b == v) {
                    if (pointOnLineLeft(u, Line(l.b, l.a))) {
                        if (pointOnLineLeft(w, Line(l.b, l.a))
                            &amp;#x26;&amp;#x26; pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    } else {
                        if (pointOnLineLeft(w, Line(l.b, l.a))
                            || pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    }
                } else {
                    if (pointOnLineLeft(u, l)) {
                        if (pointOnLineLeft(w, Line(l.b, l.a))
                            || pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    } else {
                        if (pointOnLineLeft(w, l)
                            || pointOnLineLeft(w, Line(u, v))) {
                            return false;
                        }
                    }
                }
            }
        }
    }
    return true;
}

template&amp;#x3C;class T&gt;
std::vector&amp;#x3C;Point&amp;#x3C;T&gt;&gt; hp(std::vector&amp;#x3C;Line&amp;#x3C;T&gt;&gt; lines) {
    std::sort(lines.begin(), lines.end(), [&amp;#x26;](auto l1, auto l2) {
        auto d1 = l1.b - l1.a;
        auto d2 = l2.b - l2.a;

        if (sgn(d1) != sgn(d2)) {
            return sgn(d1) == 1;
        }

        return cross(d1, d2) &gt; 0;
    });

    std::deque&amp;#x3C;Line&amp;#x3C;T&gt;&gt; ls;
    std::deque&amp;#x3C;Point&amp;#x3C;T&gt;&gt; ps;
    for (auto l : lines) {
        if (ls.empty()) {
            ls.push_back(l);
            continue;
        }

        while (!ps.empty() &amp;#x26;&amp;#x26; !pointOnLineLeft(ps.back(), l)) {
            ps.pop_back();
            ls.pop_back();
        }

        while (!ps.empty() &amp;#x26;&amp;#x26; !pointOnLineLeft(ps[0], l)) {
            ps.pop_front();
            ls.pop_front();
        }

        if (cross(l.b - l.a, ls.back().b - ls.back().a) == 0) {
            if (dot(l.b - l.a, ls.back().b - ls.back().a) &gt; 0) {

                if (!pointOnLineLeft(ls.back().a, l)) {
                    assert(ls.size() == 1);
                    ls[0] = l;
                }
                continue;
            }
            return {};
        }

        ps.push_back(lineIntersection(ls.back(), l));
        ls.push_back(l);
    }

    while (!ps.empty() &amp;#x26;&amp;#x26; !pointOnLineLeft(ps.back(), ls[0])) {
        ps.pop_back();
        ls.pop_back();
    }
    if (ls.size() &amp;#x3C;= 2) {
        return {};
    }
    ps.push_back(lineIntersection(ls[0], ls.back()));

    return std::vector(ps.begin(), ps.end());
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;10 - 静态凸包&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104288/submission/201412835&quot;&gt;2023-04-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Point {
    i64 x;
    i64 y;
    Point(i64 x = 0, i64 y = 0) : x(x), y(y) {}
};

bool operator==(const Point &amp;#x26;a, const Point &amp;#x26;b) {
    return a.x == b.x &amp;#x26;&amp;#x26; a.y == b.y;
}

Point operator+(const Point &amp;#x26;a, const Point &amp;#x26;b) {
    return Point(a.x + b.x, a.y + b.y);
}

Point operator-(const Point &amp;#x26;a, const Point &amp;#x26;b) {
    return Point(a.x - b.x, a.y - b.y);
}

i64 dot(const Point &amp;#x26;a, const Point &amp;#x26;b) {
    return a.x * b.x + a.y * b.y;
}

i64 cross(const Point &amp;#x26;a, const Point &amp;#x26;b) {
    return a.x * b.y - a.y * b.x;
}

void norm(std::vector&amp;#x3C;Point&gt; &amp;#x26;h) {
    int i = 0;
    for (int j = 0; j &amp;#x3C; int(h.size()); j++) {
        if (h[j].y &amp;#x3C; h[i].y || (h[j].y == h[i].y &amp;#x26;&amp;#x26; h[j].x &amp;#x3C; h[i].x)) {
            i = j;
        }
    }
    std::rotate(h.begin(), h.begin() + i, h.end());
}

int sgn(const Point &amp;#x26;a) {
    return a.y &gt; 0 || (a.y == 0 &amp;#x26;&amp;#x26; a.x &gt; 0) ? 0 : 1;
}

std::vector&amp;#x3C;Point&gt; getHull(std::vector&amp;#x3C;Point&gt; p) {
    std::vector&amp;#x3C;Point&gt; h, l;
    std::sort(p.begin(), p.end(), [&amp;#x26;](auto a, auto b) {
        if (a.x != b.x) {
            return a.x &amp;#x3C; b.x;
        } else {
            return a.y &amp;#x3C; b.y;
        }
    });
    p.erase(std::unique(p.begin(), p.end()), p.end());
    if (p.size() &amp;#x3C;= 1) {
        return p;
    }

    for (auto a : p) {
        while (h.size() &gt; 1 &amp;#x26;&amp;#x26; cross(a - h.back(), a - h[h.size() - 2]) &amp;#x3C;= 0) {
            h.pop_back();
        }
        while (l.size() &gt; 1 &amp;#x26;&amp;#x26; cross(a - l.back(), a - l[l.size() - 2]) &gt;= 0) {
            l.pop_back();
        }
        l.push_back(a);
        h.push_back(a);
    }

    l.pop_back();
    std::reverse(h.begin(), h.end());
    h.pop_back();
    l.insert(l.end(), h.begin(), h.end());
    return l;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;11A - 多项式相关（Poly 旧版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/arc155/submissions/38664055&quot;&gt;2023-02-06&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;int&gt; rev;
std::vector&amp;#x3C;Z&gt; roots{0, 1};
void dft(std::vector&amp;#x3C;Z&gt; &amp;#x26;a) {
    int n = a.size();

    if (int(rev.size()) != n) {
        int k = __builtin_ctz(n) - 1;
        rev.resize(n);
        for (int i = 0; i &amp;#x3C; n; i++) {
            rev[i] = rev[i &gt;&gt; 1] &gt;&gt; 1 | (i &amp;#x26; 1) &amp;#x3C;&amp;#x3C; k;
        }
    }

    for (int i = 0; i &amp;#x3C; n; i++) {
        if (rev[i] &amp;#x3C; i) {
            std::swap(a[i], a[rev[i]]);
        }
    }
    if (int(roots.size()) &amp;#x3C; n) {
        int k = __builtin_ctz(roots.size());
        roots.resize(n);
        while ((1 &amp;#x3C;&amp;#x3C; k) &amp;#x3C; n) {
            Z e = power(Z(3), (P - 1) &gt;&gt; (k + 1));
            for (int i = 1 &amp;#x3C;&amp;#x3C; (k - 1); i &amp;#x3C; (1 &amp;#x3C;&amp;#x3C; k); i++) {
                roots[2 * i] = roots[i];
                roots[2 * i + 1] = roots[i] * e;
            }
            k++;
        }
    }
    for (int k = 1; k &amp;#x3C; n; k *= 2) {
        for (int i = 0; i &amp;#x3C; n; i += 2 * k) {
            for (int j = 0; j &amp;#x3C; k; j++) {
                Z u = a[i + j];
                Z v = a[i + j + k] * roots[k + j];
                a[i + j] = u + v;
                a[i + j + k] = u - v;
            }
        }
    }
}
void idft(std::vector&amp;#x3C;Z&gt; &amp;#x26;a) {
    int n = a.size();
    std::reverse(a.begin() + 1, a.end());
    dft(a);
    Z inv = (1 - P) / n;
    for (int i = 0; i &amp;#x3C; n; i++) {
        a[i] *= inv;
    }
}
struct Poly {
    std::vector&amp;#x3C;Z&gt; a;
    Poly() {}
    explicit Poly(int size, std::function&amp;#x3C;Z(int)&gt; f = [](int) { return 0; }) : a(size) {
        for (int i = 0; i &amp;#x3C; size; i++) {
            a[i] = f(i);
        }
    }
    Poly(const std::vector&amp;#x3C;Z&gt; &amp;#x26;a) : a(a) {}
    Poly(const std::initializer_list&amp;#x3C;Z&gt; &amp;#x26;a) : a(a) {}
    int size() const {
        return a.size();
    }
    void resize(int n) {
        a.resize(n);
    }
    Z operator[](int idx) const {
        if (idx &amp;#x3C; size()) {
            return a[idx];
        } else {
            return 0;
        }
    }
    Z &amp;#x26;operator[](int idx) {
        return a[idx];
    }
    Poly mulxk(int k) const {
        auto b = a;
        b.insert(b.begin(), k, 0);
        return Poly(b);
    }
    Poly modxk(int k) const {
        k = std::min(k, size());
        return Poly(std::vector&amp;#x3C;Z&gt;(a.begin(), a.begin() + k));
    }
    Poly divxk(int k) const {
        if (size() &amp;#x3C;= k) {
            return Poly();
        }
        return Poly(std::vector&amp;#x3C;Z&gt;(a.begin() + k, a.end()));
    }
    friend Poly operator+(const Poly &amp;#x26;a, const Poly &amp;#x26;b) {
        std::vector&amp;#x3C;Z&gt; res(std::max(a.size(), b.size()));
        for (int i = 0; i &amp;#x3C; int(res.size()); i++) {
            res[i] = a[i] + b[i];
        }
        return Poly(res);
    }
    friend Poly operator-(const Poly &amp;#x26;a, const Poly &amp;#x26;b) {
        std::vector&amp;#x3C;Z&gt; res(std::max(a.size(), b.size()));
        for (int i = 0; i &amp;#x3C; int(res.size()); i++) {
            res[i] = a[i] - b[i];
        }
        return Poly(res);
    }
    friend Poly operator-(const Poly &amp;#x26;a) {
        std::vector&amp;#x3C;Z&gt; res(a.size());
        for (int i = 0; i &amp;#x3C; int(res.size()); i++) {
            res[i] = -a[i];
        }
        return Poly(res);
    }
    friend Poly operator*(Poly a, Poly b) {
        if (a.size() == 0 || b.size() == 0) {
            return Poly();
        }
        if (a.size() &amp;#x3C; b.size()) {
            std::swap(a, b);
        }
        if (b.size() &amp;#x3C; 128) {
            Poly c(a.size() + b.size() - 1);
            for (int i = 0; i &amp;#x3C; a.size(); i++) {
                for (int j = 0; j &amp;#x3C; b.size(); j++) {
                    c[i + j] += a[i] * b[j];
                }
            }
            return c;
        }
        int sz = 1, tot = a.size() + b.size() - 1;
        while (sz &amp;#x3C; tot) {
            sz *= 2;
        }
        a.a.resize(sz);
        b.a.resize(sz);
        dft(a.a);
        dft(b.a);
        for (int i = 0; i &amp;#x3C; sz; ++i) {
            a.a[i] = a[i] * b[i];
        }
        idft(a.a);
        a.resize(tot);
        return a;
    }
    friend Poly operator*(Z a, Poly b) {
        for (int i = 0; i &amp;#x3C; int(b.size()); i++) {
            b[i] *= a;
        }
        return b;
    }
    friend Poly operator*(Poly a, Z b) {
        for (int i = 0; i &amp;#x3C; int(a.size()); i++) {
            a[i] *= b;
        }
        return a;
    }
    Poly &amp;#x26;operator+=(Poly b) {
        return (*this) = (*this) + b;
    }
    Poly &amp;#x26;operator-=(Poly b) {
        return (*this) = (*this) - b;
    }
    Poly &amp;#x26;operator*=(Poly b) {
        return (*this) = (*this) * b;
    }
    Poly &amp;#x26;operator*=(Z b) {
        return (*this) = (*this) * b;
    }
    Poly deriv() const {
        if (a.empty()) {
            return Poly();
        }
        std::vector&amp;#x3C;Z&gt; res(size() - 1);
        for (int i = 0; i &amp;#x3C; size() - 1; ++i) {
            res[i] = (i + 1) * a[i + 1];
        }
        return Poly(res);
    }
    Poly integr() const {
        std::vector&amp;#x3C;Z&gt; res(size() + 1);
        for (int i = 0; i &amp;#x3C; size(); ++i) {
            res[i + 1] = a[i] / (i + 1);
        }
        return Poly(res);
    }
    Poly inv(int m) const {
        Poly x{a[0].inv()};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x * (Poly{2} - modxk(k) * x)).modxk(k);
        }
        return x.modxk(m);
    }
    Poly log(int m) const {
        return (deriv() * inv(m)).integr().modxk(m);
    }
    Poly exp(int m) const {
        Poly x{1};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x * (Poly{1} - x.log(k) + modxk(k))).modxk(k);
        }
        return x.modxk(m);
    }
    Poly pow(int k, int m) const {
        int i = 0;
        while (i &amp;#x3C; size() &amp;#x26;&amp;#x26; a[i].val() == 0) {
            i++;
        }
        if (i == size() || 1LL * i * k &gt;= m) {
            return Poly(std::vector&amp;#x3C;Z&gt;(m));
        }
        Z v = a[i];
        auto f = divxk(i) * v.inv();
        return (f.log(m - i * k) * k).exp(m - i * k).mulxk(i * k) * power(v, k);
    }
    Poly sqrt(int m) const {
        Poly x{1};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x + (modxk(k) * x.inv(k)).modxk(k)) * ((P + 1) / 2);
        }
        return x.modxk(m);
    }
    Poly mulT(Poly b) const {
        if (b.size() == 0) {
            return Poly();
        }
        int n = b.size();
        std::reverse(b.a.begin(), b.a.end());
        return ((*this) * b).divxk(n - 1);
    }
    std::vector&amp;#x3C;Z&gt; eval(std::vector&amp;#x3C;Z&gt; x) const {
        if (size() == 0) {
            return std::vector&amp;#x3C;Z&gt;(x.size(), 0);
        }
        const int n = std::max(int(x.size()), size());
        std::vector&amp;#x3C;Poly&gt; q(4 * n);
        std::vector&amp;#x3C;Z&gt; ans(x.size());
        x.resize(n);
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                q[p] = Poly{1, -x[l]};
            } else {
                int m = (l + r) / 2;
                build(2 * p, l, m);
                build(2 * p + 1, m, r);
                q[p] = q[2 * p] * q[2 * p + 1];
            }
        };
        build(1, 0, n);
        std::function&amp;#x3C;void(int, int, int, const Poly &amp;#x26;)&gt; work = [&amp;#x26;](int p, int l, int r, const Poly &amp;#x26;num) {
            if (r - l == 1) {
                if (l &amp;#x3C; int(ans.size())) {
                    ans[l] = num[0];
                }
            } else {
                int m = (l + r) / 2;
                work(2 * p, l, m, num.mulT(q[2 * p + 1]).modxk(m - l));
                work(2 * p + 1, m, r, num.mulT(q[2 * p]).modxk(r - m));
            }
        };
        work(1, 0, n, mulT(q[1].inv(n)));
        return ans;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;11B - 多项式相关（Poly+MInt &amp;#x26; MLong 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/arc163/submissions/45737810&quot;&gt;2023-09-20&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;int&gt; rev;
template&amp;#x3C;int P&gt;
std::vector&amp;#x3C;MInt&amp;#x3C;P&gt;&gt; roots{0, 1};

template&amp;#x3C;int P&gt;
constexpr MInt&amp;#x3C;P&gt; findPrimitiveRoot() {
    MInt&amp;#x3C;P&gt; i = 2;
    int k = __builtin_ctz(P - 1);
    while (true) {
        if (power(i, (P - 1) / 2) != 1) {
            break;
        }
        i += 1;
    }
    return power(i, (P - 1) &gt;&gt; k);
}

template&amp;#x3C;int P&gt;
constexpr MInt&amp;#x3C;P&gt; primitiveRoot = findPrimitiveRoot&amp;#x3C;P&gt;();

template&amp;#x3C;&gt;
constexpr MInt&amp;#x3C;998244353&gt; primitiveRoot&amp;#x3C;998244353&gt; {31};

template&amp;#x3C;int P&gt;
constexpr void dft(std::vector&amp;#x3C;MInt&amp;#x3C;P&gt;&gt; &amp;#x26;a) {
    int n = a.size();

    if (int(rev.size()) != n) {
        int k = __builtin_ctz(n) - 1;
        rev.resize(n);
        for (int i = 0; i &amp;#x3C; n; i++) {
            rev[i] = rev[i &gt;&gt; 1] &gt;&gt; 1 | (i &amp;#x26; 1) &amp;#x3C;&amp;#x3C; k;
        }
    }

    for (int i = 0; i &amp;#x3C; n; i++) {
        if (rev[i] &amp;#x3C; i) {
            std::swap(a[i], a[rev[i]]);
        }
    }
    if (roots&amp;#x3C;P&gt;.size() &amp;#x3C; n) {
        int k = __builtin_ctz(roots&amp;#x3C;P&gt;.size());
        roots&amp;#x3C;P&gt;.resize(n);
        while ((1 &amp;#x3C;&amp;#x3C; k) &amp;#x3C; n) {
            auto e = power(primitiveRoot&amp;#x3C;P&gt;, 1 &amp;#x3C;&amp;#x3C; (__builtin_ctz(P - 1) - k - 1));
            for (int i = 1 &amp;#x3C;&amp;#x3C; (k - 1); i &amp;#x3C; (1 &amp;#x3C;&amp;#x3C; k); i++) {
                roots&amp;#x3C;P&gt;[2 * i] = roots&amp;#x3C;P&gt;[i];
                roots&amp;#x3C;P&gt;[2 * i + 1] = roots&amp;#x3C;P&gt;[i] * e;
            }
            k++;
        }
    }
    for (int k = 1; k &amp;#x3C; n; k *= 2) {
        for (int i = 0; i &amp;#x3C; n; i += 2 * k) {
            for (int j = 0; j &amp;#x3C; k; j++) {
                MInt&amp;#x3C;P&gt; u = a[i + j];
                MInt&amp;#x3C;P&gt; v = a[i + j + k] * roots&amp;#x3C;P&gt;[k + j];
                a[i + j] = u + v;
                a[i + j + k] = u - v;
            }
        }
    }
}

template&amp;#x3C;int P&gt;
constexpr void idft(std::vector&amp;#x3C;MInt&amp;#x3C;P&gt;&gt; &amp;#x26;a) {
    int n = a.size();
    std::reverse(a.begin() + 1, a.end());
    dft(a);
    MInt&amp;#x3C;P&gt; inv = (1 - P) / n;
    for (int i = 0; i &amp;#x3C; n; i++) {
        a[i] *= inv;
    }
}

template&amp;#x3C;int P = 998244353&gt;
struct Poly : public std::vector&amp;#x3C;MInt&amp;#x3C;P&gt;&gt; {
    using Value = MInt&amp;#x3C;P&gt;;

    Poly() : std::vector&amp;#x3C;Value&gt;() {}
    explicit constexpr Poly(int n) : std::vector&amp;#x3C;Value&gt;(n) {}

    explicit constexpr Poly(const std::vector&amp;#x3C;Value&gt; &amp;#x26;a) : std::vector&amp;#x3C;Value&gt;(a) {}
    constexpr Poly(const std::initializer_list&amp;#x3C;Value&gt; &amp;#x26;a) : std::vector&amp;#x3C;Value&gt;(a) {}

    template&amp;#x3C;class InputIt, class = std::_RequireInputIter&amp;#x3C;InputIt&gt;&gt;
    explicit constexpr Poly(InputIt first, InputIt last) : std::vector&amp;#x3C;Value&gt;(first, last) {}

    template&amp;#x3C;class F&gt;
    explicit constexpr Poly(int n, F f) : std::vector&amp;#x3C;Value&gt;(n) {
        for (int i = 0; i &amp;#x3C; n; i++) {
            (*this)[i] = f(i);
        }
    }

    constexpr Poly shift(int k) const {
        if (k &gt;= 0) {
            auto b = *this;
            b.insert(b.begin(), k, 0);
            return b;
        } else if (this-&gt;size() &amp;#x3C;= -k) {
            return Poly();
        } else {
            return Poly(this-&gt;begin() + (-k), this-&gt;end());
        }
    }
    constexpr Poly trunc(int k) const {
        Poly f = *this;
        f.resize(k);
        return f;
    }
    constexpr friend Poly operator+(const Poly &amp;#x26;a, const Poly &amp;#x26;b) {
        Poly res(std::max(a.size(), b.size()));
        for (int i = 0; i &amp;#x3C; a.size(); i++) {
            res[i] += a[i];
        }
        for (int i = 0; i &amp;#x3C; b.size(); i++) {
            res[i] += b[i];
        }
        return res;
    }
    constexpr friend Poly operator-(const Poly &amp;#x26;a, const Poly &amp;#x26;b) {
        Poly res(std::max(a.size(), b.size()));
        for (int i = 0; i &amp;#x3C; a.size(); i++) {
            res[i] += a[i];
        }
        for (int i = 0; i &amp;#x3C; b.size(); i++) {
            res[i] -= b[i];
        }
        return res;
    }
    constexpr friend Poly operator-(const Poly &amp;#x26;a) {
        std::vector&amp;#x3C;Value&gt; res(a.size());
        for (int i = 0; i &amp;#x3C; int(res.size()); i++) {
            res[i] = -a[i];
        }
        return Poly(res);
    }
    constexpr friend Poly operator*(Poly a, Poly b) {
        if (a.size() == 0 || b.size() == 0) {
            return Poly();
        }
        if (a.size() &amp;#x3C; b.size()) {
            std::swap(a, b);
        }
        int n = 1, tot = a.size() + b.size() - 1;
        while (n &amp;#x3C; tot) {
            n *= 2;
        }
        if (((P - 1) &amp;#x26; (n - 1)) != 0 || b.size() &amp;#x3C; 128) {
            Poly c(a.size() + b.size() - 1);
            for (int i = 0; i &amp;#x3C; a.size(); i++) {
                for (int j = 0; j &amp;#x3C; b.size(); j++) {
                    c[i + j] += a[i] * b[j];
                }
            }
            return c;
        }
        a.resize(n);
        b.resize(n);
        dft(a);
        dft(b);
        for (int i = 0; i &amp;#x3C; n; ++i) {
            a[i] *= b[i];
        }
        idft(a);
        a.resize(tot);
        return a;
    }
    constexpr friend Poly operator*(Value a, Poly b) {
        for (int i = 0; i &amp;#x3C; int(b.size()); i++) {
            b[i] *= a;
        }
        return b;
    }
    constexpr friend Poly operator*(Poly a, Value b) {
        for (int i = 0; i &amp;#x3C; int(a.size()); i++) {
            a[i] *= b;
        }
        return a;
    }
    constexpr friend Poly operator/(Poly a, Value b) {
        for (int i = 0; i &amp;#x3C; int(a.size()); i++) {
            a[i] /= b;
        }
        return a;
    }
    constexpr Poly &amp;#x26;operator+=(Poly b) {
        return (*this) = (*this) + b;
    }
    constexpr Poly &amp;#x26;operator-=(Poly b) {
        return (*this) = (*this) - b;
    }
    constexpr Poly &amp;#x26;operator*=(Poly b) {
        return (*this) = (*this) * b;
    }
    constexpr Poly &amp;#x26;operator*=(Value b) {
        return (*this) = (*this) * b;
    }
    constexpr Poly &amp;#x26;operator/=(Value b) {
        return (*this) = (*this) / b;
    }
    constexpr Poly deriv() const {
        if (this-&gt;empty()) {
            return Poly();
        }
        Poly res(this-&gt;size() - 1);
        for (int i = 0; i &amp;#x3C; this-&gt;size() - 1; ++i) {
            res[i] = (i + 1) * (*this)[i + 1];
        }
        return res;
    }
    constexpr Poly integr() const {
        Poly res(this-&gt;size() + 1);
        for (int i = 0; i &amp;#x3C; this-&gt;size(); ++i) {
            res[i + 1] = (*this)[i] / (i + 1);
        }
        return res;
    }
    constexpr Poly inv(int m) const {
        Poly x{(*this)[0].inv()};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x * (Poly{2} - trunc(k) * x)).trunc(k);
        }
        return x.trunc(m);
    }
    constexpr Poly log(int m) const {
        return (deriv() * inv(m)).integr().trunc(m);
    }
    constexpr Poly exp(int m) const {
        Poly x{1};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x * (Poly{1} - x.log(k) + trunc(k))).trunc(k);
        }
        return x.trunc(m);
    }
    constexpr Poly pow(int k, int m) const {
        int i = 0;
        while (i &amp;#x3C; this-&gt;size() &amp;#x26;&amp;#x26; (*this)[i] == 0) {
            i++;
        }
        if (i == this-&gt;size() || 1LL * i * k &gt;= m) {
            return Poly(m);
        }
        Value v = (*this)[i];
        auto f = shift(-i) * v.inv();
        return (f.log(m - i * k) * k).exp(m - i * k).shift(i * k) * power(v, k);
    }
    constexpr Poly sqrt(int m) const {
        Poly x{1};
        int k = 1;
        while (k &amp;#x3C; m) {
            k *= 2;
            x = (x + (trunc(k) * x.inv(k)).trunc(k)) * CInv&amp;#x3C;2, P&gt;;
        }
        return x.trunc(m);
    }
    constexpr Poly mulT(Poly b) const {
        if (b.size() == 0) {
            return Poly();
        }
        int n = b.size();
        std::reverse(b.begin(), b.end());
        return ((*this) * b).shift(-(n - 1));
    }
    constexpr std::vector&amp;#x3C;Value&gt; eval(std::vector&amp;#x3C;Value&gt; x) const {
        if (this-&gt;size() == 0) {
            return std::vector&amp;#x3C;Value&gt;(x.size(), 0);
        }
        const int n = std::max(x.size(), this-&gt;size());
        std::vector&amp;#x3C;Poly&gt; q(4 * n);
        std::vector&amp;#x3C;Value&gt; ans(x.size());
        x.resize(n);
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                q[p] = Poly{1, -x[l]};
            } else {
                int m = (l + r) / 2;
                build(2 * p, l, m);
                build(2 * p + 1, m, r);
                q[p] = q[2 * p] * q[2 * p + 1];
            }
        };
        build(1, 0, n);
        std::function&amp;#x3C;void(int, int, int, const Poly &amp;#x26;)&gt; work = [&amp;#x26;](int p, int l, int r, const Poly &amp;#x26;num) {
            if (r - l == 1) {
                if (l &amp;#x3C; int(ans.size())) {
                    ans[l] = num[0];
                }
            } else {
                int m = (l + r) / 2;
                work(2 * p, l, m, num.mulT(q[2 * p + 1]).resize(m - l));
                work(2 * p + 1, m, r, num.mulT(q[2 * p]).resize(r - m));
            }
        };
        work(1, 0, n, mulT(q[1].inv(n)));
        return ans;
    }
};

template&amp;#x3C;int P = 998244353&gt;
Poly&amp;#x3C;P&gt; berlekampMassey(const Poly&amp;#x3C;P&gt; &amp;#x26;s) {
    Poly&amp;#x3C;P&gt; c;
    Poly&amp;#x3C;P&gt; oldC;
    int f = -1;
    for (int i = 0; i &amp;#x3C; s.size(); i++) {
        auto delta = s[i];
        for (int j = 1; j &amp;#x3C;= c.size(); j++) {
            delta -= c[j - 1] * s[i - j];
        }
        if (delta == 0) {
            continue;
        }
        if (f == -1) {
            c.resize(i + 1);
            f = i;
        } else {
            auto d = oldC;
            d *= -1;
            d.insert(d.begin(), 1);
            MInt&amp;#x3C;P&gt; df1 = 0;
            for (int j = 1; j &amp;#x3C;= d.size(); j++) {
                df1 += d[j - 1] * s[f + 1 - j];
            }
            assert(df1 != 0);
            auto coef = delta / df1;
            d *= coef;
            Poly&amp;#x3C;P&gt; zeros(i - f - 1);
            zeros.insert(zeros.end(), d.begin(), d.end());
            d = zeros;
            auto temp = c;
            c += d;
            if (i - temp.size() &gt; f - oldC.size()) {
                oldC = temp;
                f = i;
            }
        }
    }
    c *= -1;
    c.insert(c.begin(), 1);
    return c;
}


template&amp;#x3C;int P = 998244353&gt;
MInt&amp;#x3C;P&gt; linearRecurrence(Poly&amp;#x3C;P&gt; p, Poly&amp;#x3C;P&gt; q, i64 n) {
    int m = q.size() - 1;
    while (n &gt; 0) {
        auto newq = q;
        for (int i = 1; i &amp;#x3C;= m; i += 2) {
            newq[i] *= -1;
        }
        auto newp = p * newq;
        newq = q * newq;
        for (int i = 0; i &amp;#x3C; m; i++) {
            p[i] = newp[i * 2 + n % 2];
        }
        for (int i = 0; i &amp;#x3C;= m; i++) {
            q[i] = newq[i * 2];
        }
        n /= 2;
    }
    return p[0] / q[0];
}

struct Comb {
    int n;
    std::vector&amp;#x3C;Z&gt; _fac;
    std::vector&amp;#x3C;Z&gt; _invfac;
    std::vector&amp;#x3C;Z&gt; _inv;

    Comb() : n{0}, _fac{1}, _invfac{1}, _inv{0} {}
    Comb(int n) : Comb() {
        init(n);
    }

    void init(int m) {
        m = std::min(m, Z::getMod() - 1);
        if (m &amp;#x3C;= n) return;
        _fac.resize(m + 1);
        _invfac.resize(m + 1);
        _inv.resize(m + 1);

        for (int i = n + 1; i &amp;#x3C;= m; i++) {
            _fac[i] = _fac[i - 1] * i;
        }
        _invfac[m] = _fac[m].inv();
        for (int i = m; i &gt; n; i--) {
            _invfac[i - 1] = _invfac[i] * i;
            _inv[i] = _invfac[i] * _fac[i - 1];
        }
        n = m;
    }

    Z fac(int m) {
        if (m &gt; n) init(2 * m);
        return _fac[m];
    }
    Z invfac(int m) {
        if (m &gt; n) init(2 * m);
        return _invfac[m];
    }
    Z inv(int m) {
        if (m &gt; n) init(2 * m);
        return _inv[m];
    }
    Z binom(int n, int m) {
        if (n &amp;#x3C; m || m &amp;#x3C; 0) return 0;
        return fac(n) * invfac(m) * invfac(n - m);
    }
} comb;

Poly&amp;#x3C;P&gt; get(int n, int m) {
    if (m == 0) {
        return Poly(n + 1);
    }
    if (m % 2 == 1) {
        auto f = get(n, m - 1);
        Z p = 1;
        for (int i = 0; i &amp;#x3C;= n; i++) {
            f[n - i] += comb.binom(n, i) * p;
            p *= m;
        }
        return f;
    }
    auto f = get(n, m / 2);
    auto fm = f;
    for (int i = 0; i &amp;#x3C;= n; i++) {
        fm[i] *= comb.fac(i);
    }
    Poly pw(n + 1);
    pw[0] = 1;
    for (int i = 1; i &amp;#x3C;= n; i++) {
        pw[i] = pw[i - 1] * (m / 2);
    }
    for (int i = 0; i &amp;#x3C;= n; i++) {
        pw[i] *= comb.invfac(i);
    }
    fm = fm.mulT(pw);
    for (int i = 0; i &amp;#x3C;= n; i++) {
        fm[i] *= comb.invfac(i);
    }
    return f + fm;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h1&gt;四、数据结构&lt;/h1&gt;
&lt;h2&gt;01A - 树状数组（Fenwick 旧版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63382128&quot;&gt;2023-08-11&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template &amp;#x3C;typename T&gt;
struct Fenwick {
    int n;
    std::vector&amp;#x3C;T&gt; a;

    Fenwick(int n = 0) {
        init(n);
    }

    void init(int n) {
        this-&gt;n = n;
        a.assign(n, T());
    }

    void add(int x, T v) {
        for (int i = x + 1; i &amp;#x3C;= n; i += i &amp;#x26; -i) {
            a[i - 1] += v;
        }
    }

    T sum(int x) {
        auto ans = T();
        for (int i = x; i &gt; 0; i -= i &amp;#x26; -i) {
            ans += a[i - 1];
        }
        return ans;
    }

    T rangeSum(int l, int r) {
        return sum(r) - sum(l);
    }

    int kth(T k) {
        int x = 0;
        for (int i = 1 &amp;#x3C;&amp;#x3C; std::__lg(n); i; i /= 2) {
            if (x + i &amp;#x3C;= n &amp;#x26;&amp;#x26; k &gt;= a[x + i - 1]) {
                x += i;
                k -= a[x - 1];
            }
        }
        return x;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;01B - 树状数组（Fenwick 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1915/submission/239262801&quot;&gt;2023-12-28&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template &amp;#x3C;typename T&gt;
struct Fenwick {
    int n;
    std::vector&amp;#x3C;T&gt; a;

    Fenwick(int n_ = 0) {
        init(n_);
    }

    void init(int n_) {
        n = n_;
        a.assign(n, T{});
    }

    void add(int x, const T &amp;#x26;v) {
        for (int i = x + 1; i &amp;#x3C;= n; i += i &amp;#x26; -i) {
            a[i - 1] = a[i - 1] + v;
        }
    }

    T sum(int x) {
        T ans{};
        for (int i = x; i &gt; 0; i -= i &amp;#x26; -i) {
            ans = ans + a[i - 1];
        }
        return ans;
    }

    T rangeSum(int l, int r) {
        return sum(r) - sum(l);
    }

    int select(const T &amp;#x26;k) {
        int x = 0;
        T cur{};
        for (int i = 1 &amp;#x3C;&amp;#x3C; std::__lg(n); i; i /= 2) {
            if (x + i &amp;#x3C;= n &amp;#x26;&amp;#x26; cur + a[x + i - 1] &amp;#x3C;= k) {
                x += i;
                cur = cur + a[x - 1];
            }
        }
        return x;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;02 - 并查集（DSU）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63239142&quot;&gt;2023-08-04&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct DSU {
    std::vector&amp;#x3C;int&gt; f, siz;

    DSU() {}
    DSU(int n) {
        init(n);
    }

    void init(int n) {
        f.resize(n);
        std::iota(f.begin(), f.end(), 0);
        siz.assign(n, 1);
    }

    int find(int x) {
        while (x != f[x]) {
            x = f[x] = f[f[x]];
        }
        return x;
    }

    bool same(int x, int y) {
        return find(x) == find(y);
    }

    bool merge(int x, int y) {
        x = find(x);
        y = find(y);
        if (x == y) {
            return false;
        }
        siz[x] += siz[y];
        f[y] = x;
        return true;
    }

    int size(int x) {
        return siz[find(x)];
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03A - 线段树（SegmentTree 基础区间加乘）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104417/submission/223800089&quot;&gt;2023-10-18&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct SegmentTree {
    int n;
    std::vector&amp;#x3C;int&gt; tag, sum;
    SegmentTree(int n_) : n(n_), tag(4 * n, 1), sum(4 * n) {}

    void pull(int p) {
        sum[p] = (sum[2 * p] + sum[2 * p + 1]) % P;
    }

    void mul(int p, int v) {
        tag[p] = 1LL * tag[p] * v % P;
        sum[p] = 1LL * sum[p] * v % P;
    }

    void push(int p) {
        mul(2 * p, tag[p]);
        mul(2 * p + 1, tag[p]);
        tag[p] = 1;
    }

    int query(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return 0;
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return sum[p];
        }
        int m = (l + r) / 2;
        push(p);
        return (query(2 * p, l, m, x, y) + query(2 * p + 1, m, r, x, y)) % P;
    }

    int query(int x, int y) {
        return query(1, 0, n, x, y);
    }

    void rangeMul(int p, int l, int r, int x, int y, int v) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return;
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return mul(p, v);
        }
        int m = (l + r) / 2;
        push(p);
        rangeMul(2 * p, l, m, x, y, v);
        rangeMul(2 * p + 1, m, r, x, y, v);
        pull(p);
    }

    void rangeMul(int x, int y, int v) {
        rangeMul(1, 0, n, x, y, v);
    }

    void add(int p, int l, int r, int x, int v) {
        if (r - l == 1) {
            sum[p] = (sum[p] + v) % P;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        if (x &amp;#x3C; m) {
            add(2 * p, l, m, x, v);
        } else {
            add(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }

    void add(int x, int v) {
        add(1, 0, n, x, v);
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03B - 线段树（SegmentTree+Info 查找前驱后继）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63382128&quot;&gt;2023-08-11&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class Info&gt;
struct SegmentTree {
    int n;
    std::vector&amp;#x3C;Info&gt; info;
    SegmentTree() : n(0) {}
    SegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template&amp;#x3C;class T&gt;
    SegmentTree(std::vector&amp;#x3C;T&gt; init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template&amp;#x3C;class T&gt;
    void init(std::vector&amp;#x3C;T&gt; init_) {
        n = init_.size();
        info.assign(4 &amp;#x3C;&amp;#x3C; std::__lg(n), Info());
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init_[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void modify(int p, int l, int r, int x, const Info &amp;#x26;v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        if (x &amp;#x3C; m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &amp;#x26;v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return Info();
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findFirst(2 * p, l, m, x, y, pred);
        if (res == -1) {
            res = findFirst(2 * p + 1, m, r, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int l, int r, F pred) {
        return findFirst(1, 0, n, l, r, pred);
    }
    template&amp;#x3C;class F&gt;
    int findLast(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findLast(2 * p + 1, m, r, x, y, pred);
        if (res == -1) {
            res = findLast(2 * p, l, m, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findLast(int l, int r, F pred) {
        return findLast(1, 0, n, l, r, pred);
    }
};
struct Info {
    int cnt = 0;
    i64 sum = 0;
    i64 ans = 0;
};
Info operator+(Info a, Info b) {
    Info c;
    c.cnt = a.cnt + b.cnt;
    c.sum = a.sum + b.sum;
    c.ans = a.ans + b.ans + a.cnt * b.sum - a.sum * b.cnt;
    return c;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03C - 线段树（SegmentTree+Info+Merge 区间合并）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1672/submission/154766851&quot;&gt;2022-04-23&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class Info&gt;
struct SegmentTree {
    int n;
    std::vector&amp;#x3C;Info&gt; info;
    SegmentTree() : n(0) {}
    SegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template&amp;#x3C;class T&gt;
    SegmentTree(std::vector&amp;#x3C;T&gt; init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template&amp;#x3C;class T&gt;
    void init(std::vector&amp;#x3C;T&gt; init_) {
        n = init_.size();
        info.assign(4 &amp;#x3C;&amp;#x3C; std::__lg(n), Info());
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init_[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void modify(int p, int l, int r, int x, const Info &amp;#x26;v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        if (x &amp;#x3C; m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &amp;#x26;v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return Info();
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findFirst(2 * p, l, m, x, y, pred);
        if (res == -1) {
            res = findFirst(2 * p + 1, m, r, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int l, int r, F pred) {
        return findFirst(1, 0, n, l, r, pred);
    }
    template&amp;#x3C;class F&gt;
    int findLast(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        int res = findLast(2 * p + 1, m, r, x, y, pred);
        if (res == -1) {
            res = findLast(2 * p, l, m, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findLast(int l, int r, F pred) {
        return findLast(1, 0, n, l, r, pred);
    }
};

struct Info {
    int x = 0;
    int cnt = 0;
};

Info operator+(Info a, Info b) {
    if (a.x == b.x) {
        return {a.x, a.cnt + b.cnt};
    } else if (a.cnt &gt; b.cnt) {
        return {a.x, a.cnt - b.cnt};
    } else {
        return {b.x, b.cnt - a.cnt};
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04A - 懒标记线段树（LazySegmentTree 基础区间修改）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=62804432&quot;&gt;2023-07-17&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class Info, class Tag&gt;
struct LazySegmentTree {
    const int n;
    std::vector&amp;#x3C;Info&gt; info;
    std::vector&amp;#x3C;Tag&gt; tag;
    LazySegmentTree(int n) : n(n), info(4 &amp;#x3C;&amp;#x3C; std::__lg(n)), tag(4 &amp;#x3C;&amp;#x3C; std::__lg(n)) {}
    LazySegmentTree(std::vector&amp;#x3C;Info&gt; init) : LazySegmentTree(init.size()) {
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void apply(int p, const Tag &amp;#x26;v) {
        info[p].apply(v);
        tag[p].apply(v);
    }
    void push(int p) {
        apply(2 * p, tag[p]);
        apply(2 * p + 1, tag[p]);
        tag[p] = Tag();
    }
    void modify(int p, int l, int r, int x, const Info &amp;#x26;v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        if (x &amp;#x3C; m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &amp;#x26;v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return Info();
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        push(p);
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    void rangeApply(int p, int l, int r, int x, int y, const Tag &amp;#x26;v) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return;
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            apply(p, v);
            return;
        }
        int m = (l + r) / 2;
        push(p);
        rangeApply(2 * p, l, m, x, y, v);
        rangeApply(2 * p + 1, m, r, x, y, v);
        pull(p);
    }
    void rangeApply(int l, int r, const Tag &amp;#x26;v) {
        return rangeApply(1, 0, n, l, r, v);
    }
    void half(int p, int l, int r) {
        if (info[p].act == 0) {
            return;
        }
        if ((info[p].min + 1) / 2 == (info[p].max + 1) / 2) {
            apply(p, {-(info[p].min + 1) / 2});
            return;
        }
        int m = (l + r) / 2;
        push(p);
        half(2 * p, l, m);
        half(2 * p + 1, m, r);
        pull(p);
    }
    void half() {
        half(1, 0, n);
    }
};

constexpr i64 inf = 1E18;

struct Tag {
    i64 add = 0;

    void apply(Tag t) {
        add += t.add;
    }
};

struct Info {
    i64 min = inf;
    i64 max = -inf;
    i64 sum = 0;
    i64 act = 0;

    void apply(Tag t) {
        min += t.add;
        max += t.add;
        sum += act * t.add;
    }
};

Info operator+(Info a, Info b) {
    Info c;
    c.min = std::min(a.min, b.min);
    c.max = std::max(a.max, b.max);
    c.sum = a.sum + b.sum;
    c.act = a.act + b.act;
    return c;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04B - 懒标记线段树（LazySegmentTree 查找前驱后继）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=62804432&quot;&gt;2023-07-17&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class Info, class Tag&gt;
struct LazySegmentTree {
    int n;
    std::vector&amp;#x3C;Info&gt; info;
    std::vector&amp;#x3C;Tag&gt; tag;
    LazySegmentTree() : n(0) {}
    LazySegmentTree(int n_, Info v_ = Info()) {
        init(n_, v_);
    }
    template&amp;#x3C;class T&gt;
    LazySegmentTree(std::vector&amp;#x3C;T&gt; init_) {
        init(init_);
    }
    void init(int n_, Info v_ = Info()) {
        init(std::vector(n_, v_));
    }
    template&amp;#x3C;class T&gt;
    void init(std::vector&amp;#x3C;T&gt; init_) {
        n = init_.size();
        info.assign(4 &amp;#x3C;&amp;#x3C; std::__lg(n), Info());
        tag.assign(4 &amp;#x3C;&amp;#x3C; std::__lg(n), Tag());
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init_[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void apply(int p, const Tag &amp;#x26;v) {
        info[p].apply(v);
        tag[p].apply(v);
    }
    void push(int p) {
        apply(2 * p, tag[p]);
        apply(2 * p + 1, tag[p]);
        tag[p] = Tag();
    }
    void modify(int p, int l, int r, int x, const Info &amp;#x26;v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        if (x &amp;#x3C; m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &amp;#x26;v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return Info();
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        push(p);
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    void rangeApply(int p, int l, int r, int x, int y, const Tag &amp;#x26;v) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return;
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            apply(p, v);
            return;
        }
        int m = (l + r) / 2;
        push(p);
        rangeApply(2 * p, l, m, x, y, v);
        rangeApply(2 * p + 1, m, r, x, y, v);
        pull(p);
    }
    void rangeApply(int l, int r, const Tag &amp;#x26;v) {
        return rangeApply(1, 0, n, l, r, v);
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        push(p);
        int res = findFirst(2 * p, l, m, x, y, pred);
        if (res == -1) {
            res = findFirst(2 * p + 1, m, r, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findFirst(int l, int r, F pred) {
        return findFirst(1, 0, n, l, r, pred);
    }
    template&amp;#x3C;class F&gt;
    int findLast(int p, int l, int r, int x, int y, F pred) {
        if (l &gt;= y || r &amp;#x3C;= x || !pred(info[p])) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
        int m = (l + r) / 2;
        push(p);
        int res = findLast(2 * p + 1, m, r, x, y, pred);
        if (res == -1) {
            res = findLast(2 * p, l, m, x, y, pred);
        }
        return res;
    }
    template&amp;#x3C;class F&gt;
    int findLast(int l, int r, F pred) {
        return findLast(1, 0, n, l, r, pred);
    }
};

struct Tag {
    i64 a = 0, b = 0;
    void apply(Tag t) {
        a = std::min(a, b + t.a);
        b += t.b;
    }
};

int k;

struct Info {
    i64 x = 0;
    void apply(Tag t) {
        x += t.a;
        if (x &amp;#x3C; 0) {
            x = (x % k + k) % k;
        }
        x += t.b - t.a;
    }
};
Info operator+(Info a, Info b) {
    return {a.x + b.x};
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04C - 懒标记线段树（LazySegmentTree 二分修改）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/joi2023yo2/submissions/39363123&quot;&gt;2023-03-03&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;constexpr int inf = 1E9 + 1;
template&amp;#x3C;class Info, class Tag&gt;
struct LazySegmentTree {
    const int n;
    std::vector&amp;#x3C;Info&gt; info;
    std::vector&amp;#x3C;Tag&gt; tag;
    LazySegmentTree(int n) : n(n), info(4 &amp;#x3C;&amp;#x3C; std::__lg(n)), tag(4 &amp;#x3C;&amp;#x3C; std::__lg(n)) {}
    LazySegmentTree(std::vector&amp;#x3C;Info&gt; init) : LazySegmentTree(init.size()) {
        std::function&amp;#x3C;void(int, int, int)&gt; build = [&amp;#x26;](int p, int l, int r) {
            if (r - l == 1) {
                info[p] = init[l];
                return;
            }
            int m = (l + r) / 2;
            build(2 * p, l, m);
            build(2 * p + 1, m, r);
            pull(p);
        };
        build(1, 0, n);
    }
    void pull(int p) {
        info[p] = info[2 * p] + info[2 * p + 1];
    }
    void apply(int p, const Tag &amp;#x26;v) {
        info[p].apply(v);
        tag[p].apply(v);
    }
    void push(int p) {
        apply(2 * p, tag[p]);
        apply(2 * p + 1, tag[p]);
        tag[p] = Tag();
    }
    void modify(int p, int l, int r, int x, const Info &amp;#x26;v) {
        if (r - l == 1) {
            info[p] = v;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        if (x &amp;#x3C; m) {
            modify(2 * p, l, m, x, v);
        } else {
            modify(2 * p + 1, m, r, x, v);
        }
        pull(p);
    }
    void modify(int p, const Info &amp;#x26;v) {
        modify(1, 0, n, p, v);
    }
    Info rangeQuery(int p, int l, int r, int x, int y) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return Info();
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            return info[p];
        }
        int m = (l + r) / 2;
        push(p);
        return rangeQuery(2 * p, l, m, x, y) + rangeQuery(2 * p + 1, m, r, x, y);
    }
    Info rangeQuery(int l, int r) {
        return rangeQuery(1, 0, n, l, r);
    }
    void rangeApply(int p, int l, int r, int x, int y, const Tag &amp;#x26;v) {
        if (l &gt;= y || r &amp;#x3C;= x) {
            return;
        }
        if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
            apply(p, v);
            return;
        }
        int m = (l + r) / 2;
        push(p);
        rangeApply(2 * p, l, m, x, y, v);
        rangeApply(2 * p + 1, m, r, x, y, v);
        pull(p);
    }
    void rangeApply(int l, int r, const Tag &amp;#x26;v) {
        return rangeApply(1, 0, n, l, r, v);
    }
    void maintainL(int p, int l, int r, int pre) {
        if (info[p].difl &gt; 0 &amp;#x26;&amp;#x26; info[p].maxlowl &amp;#x3C; pre) {
            return;
        }
        if (r - l == 1) {
            info[p].max = info[p].maxlowl;
            info[p].maxl = info[p].maxr = l;
            info[p].maxlowl = info[p].maxlowr = -inf;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        maintainL(2 * p, l, m, pre);
        pre = std::max(pre, info[2 * p].max);
        maintainL(2 * p + 1, m, r, pre);
        pull(p);
    }
    void maintainL() {
        maintainL(1, 0, n, -1);
    }
    void maintainR(int p, int l, int r, int suf) {
        if (info[p].difr &gt; 0 &amp;#x26;&amp;#x26; info[p].maxlowr &amp;#x3C; suf) {
            return;
        }
        if (r - l == 1) {
            info[p].max = info[p].maxlowl;
            info[p].maxl = info[p].maxr = l;
            info[p].maxlowl = info[p].maxlowr = -inf;
            return;
        }
        int m = (l + r) / 2;
        push(p);
        maintainR(2 * p + 1, m, r, suf);
        suf = std::max(suf, info[2 * p + 1].max);
        maintainR(2 * p, l, m, suf);
        pull(p);
    }
    void maintainR() {
        maintainR(1, 0, n, -1);
    }
};

struct Tag {
    int add = 0;

    void apply(Tag t) &amp;#x26; {
        add += t.add;
    }
};

struct Info {
    int max = -1;
    int maxl = -1;
    int maxr = -1;
    int difl = inf;
    int difr = inf;
    int maxlowl = -inf;
    int maxlowr = -inf;

    void apply(Tag t) &amp;#x26; {
        if (max != -1) {
            max += t.add;
        }
        difl += t.add;
        difr += t.add;
    }
};

Info operator+(Info a, Info b) {
    Info c;
    if (a.max &gt; b.max) {
        c.max = a.max;
        c.maxl = a.maxl;
        c.maxr = a.maxr;
    } else if (a.max &amp;#x3C; b.max) {
        c.max = b.max;
        c.maxl = b.maxl;
        c.maxr = b.maxr;
    } else {
        c.max = a.max;
        c.maxl = a.maxl;
        c.maxr = b.maxr;
    }

    c.difl = std::min(a.difl, b.difl);
    c.difr = std::min(a.difr, b.difr);
    if (a.max != -1) {
        c.difl = std::min(c.difl, a.max - b.maxlowl);
    }
    if (b.max != -1) {
        c.difr = std::min(c.difr, b.max - a.maxlowr);
    }

    if (a.max == -1) {
        c.maxlowl = std::max(a.maxlowl, b.maxlowl);
    } else {
        c.maxlowl = a.maxlowl;
    }
    if (b.max == -1) {
        c.maxlowr = std::max(a.maxlowr, b.maxlowr);
    } else {
        c.maxlowr = b.maxlowr;
    }
    return c;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;05A - 取模类（MLong &amp;#x26; MInt）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1697/submission/160317720&quot;&gt;2022-06-12&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;constexpr int P = 998244353;
using i64 = long long;
// assume -P &amp;#x3C;= x &amp;#x3C; 2P
int norm(int x) {
    if (x &amp;#x3C; 0) {
        x += P;
    }
    if (x &gt;= P) {
        x -= P;
    }
    return x;
}
template&amp;#x3C;class T&gt;
T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}
struct Z {
    int x;
    Z(int x = 0) : x(norm(x)) {}
    Z(i64 x) : x(norm(x % P)) {}
    int val() const {
        return x;
    }
    Z operator-() const {
        return Z(norm(P - x));
    }
    Z inv() const {
        assert(x != 0);
        return power(*this, P - 2);
    }
    Z &amp;#x26;operator*=(const Z &amp;#x26;rhs) {
        x = i64(x) * rhs.x % P;
        return *this;
    }
    Z &amp;#x26;operator+=(const Z &amp;#x26;rhs) {
        x = norm(x + rhs.x);
        return *this;
    }
    Z &amp;#x26;operator-=(const Z &amp;#x26;rhs) {
        x = norm(x - rhs.x);
        return *this;
    }
    Z &amp;#x26;operator/=(const Z &amp;#x26;rhs) {
        return *this *= rhs.inv();
    }
    friend Z operator*(const Z &amp;#x26;lhs, const Z &amp;#x26;rhs) {
        Z res = lhs;
        res *= rhs;
        return res;
    }
    friend Z operator+(const Z &amp;#x26;lhs, const Z &amp;#x26;rhs) {
        Z res = lhs;
        res += rhs;
        return res;
    }
    friend Z operator-(const Z &amp;#x26;lhs, const Z &amp;#x26;rhs) {
        Z res = lhs;
        res -= rhs;
        return res;
    }
    friend Z operator/(const Z &amp;#x26;lhs, const Z &amp;#x26;rhs) {
        Z res = lhs;
        res /= rhs;
        return res;
    }
    friend std::istream &amp;#x26;operator&gt;&gt;(std::istream &amp;#x26;is, Z &amp;#x26;a) {
        i64 v;
        is &gt;&gt; v;
        a = Z(v);
        return is;
    }
    friend std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, const Z &amp;#x26;a) {
        return os &amp;#x3C;&amp;#x3C; a.val();
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;05B - 取模类（MLong &amp;#x26; MInt 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63433564&quot;&gt;2023-08-14&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;根据输入内容动态修改 MOD 的方法：&lt;code&gt;Z::setMod(p);&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;长度过长，点击查看&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
constexpr T power(T a, i64 b) {
    T res = 1;
    for (; b; b /= 2, a *= a) {
        if (b % 2) {
            res *= a;
        }
    }
    return res;
}

constexpr i64 mul(i64 a, i64 b, i64 p) {
    i64 res = a * b - i64(1.L * a * b / p) * p;
    res %= p;
    if (res &amp;#x3C; 0) {
        res += p;
    }
    return res;
}
template&amp;#x3C;i64 P&gt;
struct MLong {
    i64 x;
    constexpr MLong() : x{} {}
    constexpr MLong(i64 x) : x{norm(x % getMod())} {}

    static i64 Mod;
    constexpr static i64 getMod() {
        if (P &gt; 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(i64 Mod_) {
        Mod = Mod_;
    }
    constexpr i64 norm(i64 x) const {
        if (x &amp;#x3C; 0) {
            x += getMod();
        }
        if (x &gt;= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr i64 val() const {
        return x;
    }
    explicit constexpr operator i64() const {
        return x;
    }
    constexpr MLong operator-() const {
        MLong res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MLong inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MLong &amp;#x26;operator*=(MLong rhs) &amp;#x26; {
        x = mul(x, rhs.x, getMod());
        return *this;
    }
    constexpr MLong &amp;#x26;operator+=(MLong rhs) &amp;#x26; {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MLong &amp;#x26;operator-=(MLong rhs) &amp;#x26; {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MLong &amp;#x26;operator/=(MLong rhs) &amp;#x26; {
        return *this *= rhs.inv();
    }
    friend constexpr MLong operator*(MLong lhs, MLong rhs) {
        MLong res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MLong operator+(MLong lhs, MLong rhs) {
        MLong res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MLong operator-(MLong lhs, MLong rhs) {
        MLong res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MLong operator/(MLong lhs, MLong rhs) {
        MLong res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &amp;#x26;operator&gt;&gt;(std::istream &amp;#x26;is, MLong &amp;#x26;a) {
        i64 v;
        is &gt;&gt; v;
        a = MLong(v);
        return is;
    }
    friend constexpr std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, const MLong &amp;#x26;a) {
        return os &amp;#x3C;&amp;#x3C; a.val();
    }
    friend constexpr bool operator==(MLong lhs, MLong rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MLong lhs, MLong rhs) {
        return lhs.val() != rhs.val();
    }
};

template&amp;#x3C;&gt;
i64 MLong&amp;#x3C;0LL&gt;::Mod = i64(1E18) + 9;

template&amp;#x3C;int P&gt;
struct MInt {
    int x;
    constexpr MInt() : x{} {}
    constexpr MInt(i64 x) : x{norm(x % getMod())} {}

    static int Mod;
    constexpr static int getMod() {
        if (P &gt; 0) {
            return P;
        } else {
            return Mod;
        }
    }
    constexpr static void setMod(int Mod_) {
        Mod = Mod_;
    }
    constexpr int norm(int x) const {
        if (x &amp;#x3C; 0) {
            x += getMod();
        }
        if (x &gt;= getMod()) {
            x -= getMod();
        }
        return x;
    }
    constexpr int val() const {
        return x;
    }
    explicit constexpr operator int() const {
        return x;
    }
    constexpr MInt operator-() const {
        MInt res;
        res.x = norm(getMod() - x);
        return res;
    }
    constexpr MInt inv() const {
        assert(x != 0);
        return power(*this, getMod() - 2);
    }
    constexpr MInt &amp;#x26;operator*=(MInt rhs) &amp;#x26; {
        x = 1LL * x * rhs.x % getMod();
        return *this;
    }
    constexpr MInt &amp;#x26;operator+=(MInt rhs) &amp;#x26; {
        x = norm(x + rhs.x);
        return *this;
    }
    constexpr MInt &amp;#x26;operator-=(MInt rhs) &amp;#x26; {
        x = norm(x - rhs.x);
        return *this;
    }
    constexpr MInt &amp;#x26;operator/=(MInt rhs) &amp;#x26; {
        return *this *= rhs.inv();
    }
    friend constexpr MInt operator*(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res *= rhs;
        return res;
    }
    friend constexpr MInt operator+(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res += rhs;
        return res;
    }
    friend constexpr MInt operator-(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res -= rhs;
        return res;
    }
    friend constexpr MInt operator/(MInt lhs, MInt rhs) {
        MInt res = lhs;
        res /= rhs;
        return res;
    }
    friend constexpr std::istream &amp;#x26;operator&gt;&gt;(std::istream &amp;#x26;is, MInt &amp;#x26;a) {
        i64 v;
        is &gt;&gt; v;
        a = MInt(v);
        return is;
    }
    friend constexpr std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, const MInt &amp;#x26;a) {
        return os &amp;#x3C;&amp;#x3C; a.val();
    }
    friend constexpr bool operator==(MInt lhs, MInt rhs) {
        return lhs.val() == rhs.val();
    }
    friend constexpr bool operator!=(MInt lhs, MInt rhs) {
        return lhs.val() != rhs.val();
    }
};

template&amp;#x3C;&gt;
int MInt&amp;#x3C;0&gt;::Mod = 998244353;

template&amp;#x3C;int V, int P&gt;
constexpr MInt&amp;#x3C;P&gt; CInv = MInt&amp;#x3C;P&gt;(V).inv();

constexpr int P = 1000000007;
using Z = MInt&amp;#x3C;P&gt;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06 - 状压RMQ（RMQ）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/joi2022ho/submissions/39351739&quot;&gt;2023-03-02&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T,
    class Cmp = std::less&amp;#x3C;T&gt;&gt;
struct RMQ {
    const Cmp cmp = Cmp();
    static constexpr unsigned B = 64;
    using u64 = unsigned long long;
    int n;
    std::vector&amp;#x3C;std::vector&amp;#x3C;T&gt;&gt; a;
    std::vector&amp;#x3C;T&gt; pre, suf, ini;
    std::vector&amp;#x3C;u64&gt; stk;
    RMQ() {}
    RMQ(const std::vector&amp;#x3C;T&gt; &amp;#x26;v) {
        init(v);
    }
    void init(const std::vector&amp;#x3C;T&gt; &amp;#x26;v) {
        n = v.size();
        pre = suf = ini = v;
        stk.resize(n);
        if (!n) {
            return;
        }
        const int M = (n - 1) / B + 1;
        const int lg = std::__lg(M);
        a.assign(lg + 1, std::vector&amp;#x3C;T&gt;(M));
        for (int i = 0; i &amp;#x3C; M; i++) {
            a[0][i] = v[i * B];
            for (int j = 1; j &amp;#x3C; B &amp;#x26;&amp;#x26; i * B + j &amp;#x3C; n; j++) {
                a[0][i] = std::min(a[0][i], v[i * B + j], cmp);
            }
        }
        for (int i = 1; i &amp;#x3C; n; i++) {
            if (i % B) {
                pre[i] = std::min(pre[i], pre[i - 1], cmp);
            }
        }
        for (int i = n - 2; i &gt;= 0; i--) {
            if (i % B != B - 1) {
                suf[i] = std::min(suf[i], suf[i + 1], cmp);
            }
        }
        for (int j = 0; j &amp;#x3C; lg; j++) {
            for (int i = 0; i + (2 &amp;#x3C;&amp;#x3C; j) &amp;#x3C;= M; i++) {
                a[j + 1][i] = std::min(a[j][i], a[j][i + (1 &amp;#x3C;&amp;#x3C; j)], cmp);
            }
        }
        for (int i = 0; i &amp;#x3C; M; i++) {
            const int l = i * B;
            const int r = std::min(1U * n, l + B);
            u64 s = 0;
            for (int j = l; j &amp;#x3C; r; j++) {
                while (s &amp;#x26;&amp;#x26; cmp(v[j], v[std::__lg(s) + l])) {
                    s ^= 1ULL &amp;#x3C;&amp;#x3C; std::__lg(s);
                }
                s |= 1ULL &amp;#x3C;&amp;#x3C; (j - l);
                stk[j] = s;
            }
        }
    }
    T operator()(int l, int r) {
        if (l / B != (r - 1) / B) {
            T ans = std::min(suf[l], pre[r - 1], cmp);
            l = l / B + 1;
            r = r / B;
            if (l &amp;#x3C; r) {
                int k = std::__lg(r - l);
                ans = std::min({ans, a[k][l], a[k][r - (1 &amp;#x3C;&amp;#x3C; k)]}, cmp);
            }
            return ans;
        } else {
            int x = B * (l / B);
            return ini[__builtin_ctzll(stk[r - 1] &gt;&gt; (l - x)) + l];
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;07 - Splay&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/joi2023ho/submissions/38901674&quot;&gt;2023-02-15&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Node {
    Node *l = nullptr;
    Node *r = nullptr;
    int cnt = 0;
    i64 sum = 0;
};

Node *add(Node *t, int l, int r, int p, int v) {
    Node *x = new Node;
    if (t) {
        *x = *t;
    }
    x-&gt;cnt += 1;
    x-&gt;sum += v;
    if (r - l == 1) {
        return x;
    }
    int m = (l + r) / 2;
    if (p &amp;#x3C; m) {
        x-&gt;l = add(x-&gt;l, l, m, p, v);
    } else {
        x-&gt;r = add(x-&gt;r, m, r, p, v);
    }
    return x;
}

int find(Node *tl, Node *tr, int l, int r, int x) {
    if (r &amp;#x3C;= x) {
        return -1;
    }
    if (l &gt;= x) {
        int cnt = (tr ? tr-&gt;cnt : 0) - (tl ? tl-&gt;cnt : 0);
        if (cnt == 0) {
            return -1;
        }
        if (r - l == 1) {
            return l;
        }
    }
    int m = (l + r) / 2;
    int res = find(tl ? tl-&gt;l : tl, tr ? tr-&gt;l : tr, l, m, x);
    if (res == -1) {
        res = find(tl ? tl-&gt;r : tl, tr ? tr-&gt;r : tr, m, r, x);
    }
    return res;
}

std::pair&amp;#x3C;int, i64&gt; get(Node *t, int l, int r, int x, int y) {
    if (l &gt;= y || r &amp;#x3C;= x || !t) {
        return {0, 0LL};
    }
    if (l &gt;= x &amp;#x26;&amp;#x26; r &amp;#x3C;= y) {
        return {t-&gt;cnt, t-&gt;sum};
    }
    int m = (l + r) / 2;
    auto [cl, sl] = get(t-&gt;l, l, m, x, y);
    auto [cr, sr] = get(t-&gt;r, m, r, x, y);
    return {cl + cr, sl + sr};
}

struct Tree {
    int add = 0;
    int val = 0;
    int id = 0;
    Tree *ch[2] = {};
    Tree *p = nullptr;
};

int pos(Tree *t) {
    return t-&gt;p-&gt;ch[1] == t;
}

void add(Tree *t, int v) {
    t-&gt;val += v;
    t-&gt;add += v;
}

void push(Tree *t) {
    if (t-&gt;ch[0]) {
        add(t-&gt;ch[0], t-&gt;add);
    }
    if (t-&gt;ch[1]) {
        add(t-&gt;ch[1], t-&gt;add);
    }
    t-&gt;add = 0;
}

void rotate(Tree *t) {
    Tree *q = t-&gt;p;
    int x = !pos(t);
    q-&gt;ch[!x] = t-&gt;ch[x];
    if (t-&gt;ch[x]) t-&gt;ch[x]-&gt;p = q;
    t-&gt;p = q-&gt;p;
    if (q-&gt;p) q-&gt;p-&gt;ch[pos(q)] = t;
    t-&gt;ch[x] = q;
    q-&gt;p = t;
}

void splay(Tree *t) {
    std::vector&amp;#x3C;Tree *&gt; s;
    for (Tree *i = t; i-&gt;p; i = i-&gt;p) s.push_back(i-&gt;p);
    while (!s.empty()) {
        push(s.back());
        s.pop_back();
    }
    push(t);
    while (t-&gt;p) {
        if (t-&gt;p-&gt;p) {
            if (pos(t) == pos(t-&gt;p)) rotate(t-&gt;p);
            else rotate(t);
        }
        rotate(t);
    }
}

void insert(Tree *&amp;#x26;t, Tree *x, Tree *p = nullptr) {
    if (!t) {
        t = x;
        x-&gt;p = p;
        return;
    }

    push(t);
    if (x-&gt;val &amp;#x3C; t-&gt;val) {
        insert(t-&gt;ch[0], x, t);
    } else {
        insert(t-&gt;ch[1], x, t);
    }
}

void dfs(Tree *t) {
    if (!t) {
        return;
    }
    push(t);
    dfs(t-&gt;ch[0]);
    std::cerr &amp;#x3C;&amp;#x3C; t-&gt;val &amp;#x3C;&amp;#x3C; &quot; &quot;;
    dfs(t-&gt;ch[1]);
}

std::pair&amp;#x3C;Tree *, Tree *&gt; split(Tree *t, int x) {
    if (!t) {
        return {t, t};
    }
    Tree *v = nullptr;
    Tree *j = t;
    for (Tree *i = t; i; ) {
        push(i);
        j = i;
        if (i-&gt;val &gt;= x) {
            v = i;
            i = i-&gt;ch[0];
        } else {
            i = i-&gt;ch[1];
        }
    }

    splay(j);
    if (!v) {
        return {j, nullptr};
    }

    splay(v);

    Tree *u = v-&gt;ch[0];
    if (u) {
        v-&gt;ch[0] = u-&gt;p = nullptr;
    }
    // std::cerr &amp;#x3C;&amp;#x3C; &quot;split &quot; &amp;#x3C;&amp;#x3C; x &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
    // dfs(u);
    // std::cerr &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
    // dfs(v);
    // std::cerr &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
    return {u, v};
}

Tree *merge(Tree *l, Tree *r) {
    if (!l) {
        return r;
    }
    if (!r) {
        return l;
    }
    Tree *i = l;
    while (i-&gt;ch[1]) {
        i = i-&gt;ch[1];
    }
    splay(i);
    i-&gt;ch[1] = r;
    r-&gt;p = i;
    return i;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104479/submission/221036520&quot;&gt;2023-09-30&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Node {
    Node *ch[2], *p;
    bool rev;
    int siz = 1;
    Node() : ch{nullptr, nullptr}, p(nullptr), rev(false) {}
};
void reverse(Node *t) {
    if (t) {
        std::swap(t-&gt;ch[0], t-&gt;ch[1]);
        t-&gt;rev ^= 1;
    }
}
void push(Node *t) {
    if (t-&gt;rev) {
        reverse(t-&gt;ch[0]);
        reverse(t-&gt;ch[1]);
        t-&gt;rev = false;
    }
}
void pull(Node *t) {
    t-&gt;siz = (t-&gt;ch[0] ? t-&gt;ch[0]-&gt;siz : 0) + 1 + (t-&gt;ch[1] ? t-&gt;ch[1]-&gt;siz : 0);
}
bool isroot(Node *t) {
    return t-&gt;p == nullptr || (t-&gt;p-&gt;ch[0] != t &amp;#x26;&amp;#x26; t-&gt;p-&gt;ch[1] != t);
}
int pos(Node *t) {
    return t-&gt;p-&gt;ch[1] == t;
}
void pushAll(Node *t) {
    if (!isroot(t)) {
        pushAll(t-&gt;p);
    }
    push(t);
}
void rotate(Node *t) {
    Node *q = t-&gt;p;
    int x = !pos(t);
    q-&gt;ch[!x] = t-&gt;ch[x];
    if (t-&gt;ch[x]) {
        t-&gt;ch[x]-&gt;p = q;
    }
    t-&gt;p = q-&gt;p;
    if (!isroot(q)) {
        q-&gt;p-&gt;ch[pos(q)] = t;
    }
    t-&gt;ch[x] = q;
    q-&gt;p = t;
    pull(q);
}
void splay(Node *t) {
    pushAll(t);
    while (!isroot(t)) {
        if (!isroot(t-&gt;p)) {
            if (pos(t) == pos(t-&gt;p)) {
                rotate(t-&gt;p);
            } else {
                rotate(t);
            }
        }
        rotate(t);
    }
    pull(t);
}
void access(Node *t) {
    for (Node *i = t, *q = nullptr; i; q = i, i = i-&gt;p) {
        splay(i);
        i-&gt;ch[1] = q;
        pull(i);
    }
    splay(t);
}
void makeroot(Node *t) {
    access(t);
    reverse(t);
}
void link(Node *x, Node *y) {
    makeroot(x);
    x-&gt;p = y;
}
void split(Node *x, Node *y) {
    makeroot(x);
    access(y);
}
void cut(Node *x, Node *y) {
    split(x, y);
    x-&gt;p = y-&gt;ch[0] = nullptr;
    pull(y);
}
int dist(Node *x, Node *y) {
    split(x, y);
    return y-&gt;siz - 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1942/submission/254202464&quot;&gt;2024-03-30&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Matrix : std::array&amp;#x3C;std::array&amp;#x3C;i64, 4&gt;, 4&gt; {
    Matrix(i64 v = 0) {
        for (int i = 0; i &amp;#x3C; 4; i++) {
            for (int j = 0; j &amp;#x3C; 4; j++) {
                (*this)[i][j] = (i == j ? v : inf);
            }
        }
    }
};

Matrix operator*(const Matrix &amp;#x26;a, const Matrix &amp;#x26;b) {
    Matrix c(inf);
    for (int i = 0; i &amp;#x3C; 3; i++) {
        for (int j = 0; j &amp;#x3C; 3; j++) {
            for (int k = 0; k &amp;#x3C; 4; k++) {
                c[i][k] = std::min(c[i][k], a[i][j] + b[j][k]);
            }
        }
        c[i][3] = std::min(c[i][3], a[i][3]);
    }
    c[3][3] = 0;
    return c;
}

struct Node {
    Node *ch[2], *p;
    i64 sumg = 0;
    i64 sumh = 0;
    i64 sumb = 0;
    i64 g = 0;
    i64 h = 0;
    i64 b = 0;
    Matrix mat;
    Matrix prd;
    std::array&amp;#x3C;i64, 4&gt; ans{};
    Node() : ch{nullptr, nullptr}, p(nullptr) {}

    void update() {
        mat = Matrix(inf);
        mat[0][0] = b + h - g + sumg;
        mat[1][1] = mat[1][2] = mat[1][3] = h + sumh;
        mat[2][0] = mat[2][1] = mat[2][2] = mat[2][3] = b + h + sumb;
        mat[3][3] = 0;
    }
};
void push(Node *t) {

}
void pull(Node *t) {
    t-&gt;prd = (t-&gt;ch[0] ? t-&gt;ch[0]-&gt;prd : Matrix()) * t-&gt;mat * (t-&gt;ch[1] ? t-&gt;ch[1]-&gt;prd : Matrix());
}
bool isroot(Node *t) {
    return t-&gt;p == nullptr || (t-&gt;p-&gt;ch[0] != t &amp;#x26;&amp;#x26; t-&gt;p-&gt;ch[1] != t);
}
int pos(Node *t) {
    return t-&gt;p-&gt;ch[1] == t;
}
void pushAll(Node *t) {
    if (!isroot(t)) {
        pushAll(t-&gt;p);
    }
    push(t);
}
void rotate(Node *t) {
    Node *q = t-&gt;p;
    int x = !pos(t);
    q-&gt;ch[!x] = t-&gt;ch[x];
    if (t-&gt;ch[x]) {
        t-&gt;ch[x]-&gt;p = q;
    }
    t-&gt;p = q-&gt;p;
    if (!isroot(q)) {
        q-&gt;p-&gt;ch[pos(q)] = t;
    }
    t-&gt;ch[x] = q;
    q-&gt;p = t;
    pull(q);
}
void splay(Node *t) {
    pushAll(t);
    while (!isroot(t)) {
        if (!isroot(t-&gt;p)) {
            if (pos(t) == pos(t-&gt;p)) {
                rotate(t-&gt;p);
            } else {
                rotate(t);
            }
        }
        rotate(t);
    }
    pull(t);
}

std::array&amp;#x3C;i64, 4&gt; get(Node *t) {
    std::array&amp;#x3C;i64, 4&gt; ans;
    ans.fill(inf);
    ans[3] = 0;
    for (int i = 0; i &amp;#x3C; 3; i++) {
        for (int j = 0; j &amp;#x3C; 4; j++) {
            ans[i] = std::min(ans[i], t-&gt;prd[i][j]);
        }
    }
    return ans;
}

void access(Node *t) {
    std::array&amp;#x3C;i64, 4&gt; old{};
    for (Node *i = t, *q = nullptr; i; q = i, i = i-&gt;p) {
        splay(i);
        if (i-&gt;ch[1]) {
            auto res = get(i-&gt;ch[1]);
            i-&gt;sumg += res[0];
            i-&gt;sumh += std::min({res[1], res[2], res[3]});
            i-&gt;sumb += std::min({res[0], res[1], res[2], res[3]});
        }
        i-&gt;ch[1] = q;
        i-&gt;sumg -= old[0];
        i-&gt;sumh -= std::min({old[1], old[2], old[3]});
        i-&gt;sumb -= std::min({old[0], old[1], old[2], old[3]});
        old = get(i);
        i-&gt;update();
        pull(i);
    }
    splay(t);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;08 - 其他平衡树&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63246177&quot;&gt;2023-08-04&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Node {
    Node *l = nullptr;
    Node *r = nullptr;
    int sum = 0;
    int sumodd = 0;

    Node(Node *t) {
        if (t) {
            *this = *t;
        }
    }
};

Node *add(Node *t, int l, int r, int x, int v) {
    t = new Node(t);
    t-&gt;sum += v;
    t-&gt;sumodd += (x % 2) * v;
    if (r - l == 1) {
        return t;
    }
    int m = (l + r) / 2;
    if (x &amp;#x3C; m) {
        t-&gt;l = add(t-&gt;l, l, m, x, v);
    } else {
        t-&gt;r = add(t-&gt;r, m, r, x, v);
    }
    return t;
}

int query1(Node *t1, Node *t2, int l, int r, int k) {
    if (r - l == 1) {
        return l;
    }
    int m = (l + r) / 2;
    int odd = (t1 &amp;#x26;&amp;#x26; t1-&gt;r ? t1-&gt;r-&gt;sumodd : 0) - (t2 &amp;#x26;&amp;#x26; t2-&gt;r ? t2-&gt;r-&gt;sumodd : 0);
    int cnt = (t1 &amp;#x26;&amp;#x26; t1-&gt;r ? t1-&gt;r-&gt;sum : 0) - (t2 &amp;#x26;&amp;#x26; t2-&gt;r ? t2-&gt;r-&gt;sum : 0);
    if (odd &gt; 0 || cnt &gt; k) {
        return query1(t1 ? t1-&gt;r : t1, t2 ? t2-&gt;r : t2, m, r, k);
    } else {
        return query1(t1 ? t1-&gt;l : t1, t2 ? t2-&gt;l : t2, l, m, k - cnt);
    }
}

std::array&amp;#x3C;int, 3&gt; query2(Node *t1, Node *t2, int l, int r, int k) {
    if (r - l == 1) {
        int cnt = (t1 ? t1-&gt;sumodd : 0) - (t2 ? t2-&gt;sumodd : 0);
        return {l, cnt, k};
    }
    int m = (l + r) / 2;
    int cnt = (t1 &amp;#x26;&amp;#x26; t1-&gt;r ? t1-&gt;r-&gt;sumodd : 0) - (t2 &amp;#x26;&amp;#x26; t2-&gt;r ? t2-&gt;r-&gt;sumodd : 0);
    if (cnt &gt; k) {
        return query2(t1 ? t1-&gt;r : t1, t2 ? t2-&gt;r : t2, m, r, k);
    } else {
        return query2(t1 ? t1-&gt;l : t1, t2 ? t2-&gt;l : t2, l, m, k - cnt);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1864/submission/220558951&quot;&gt;2023-08-26&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Node {
    Node *l = nullptr;
    Node *r = nullptr;
    int cnt = 0;
};

Node *add(Node *t, int l, int r, int x) {
    if (t) {
        t = new Node(*t);
    } else {
        t = new Node;
    }
    t-&gt;cnt += 1;
    if (r - l == 1) {
        return t;
    }
    int m = (l + r) / 2;
    if (x &amp;#x3C; m) {
        t-&gt;l = add(t-&gt;l, l, m, x);
    } else {
        t-&gt;r = add(t-&gt;r, m, r, x);
    }
    return t;
}

int query(Node *t1, Node *t2, int l, int r, int x) {
    int cnt = (t2 ? t2-&gt;cnt : 0) - (t1 ? t1-&gt;cnt : 0);
    if (cnt == 0 || l &gt;= x) {
        return -1;
    }
    if (r - l == 1) {
        return l;
    }
    int m = (l + r) / 2;
    int res = query(t1 ? t1-&gt;r : t1, t2 ? t2-&gt;r : t2, m, r, x);
    if (res == -1) {
        res = query(t1 ? t1-&gt;l : t1, t2 ? t2-&gt;l : t2, l, m, x);
    }
    return res;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/38/submission/200537139&quot;&gt;2023-04-03&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Info {
    int imp = 0;
    int id = 0;
};

Info operator+(Info a, Info b) {
    return {std::max(a.imp, b.imp), 0};
}

struct Node {
    int w = rng();
    Info info;
    Info sum;
    int siz = 1;
    Node *l = nullptr;
    Node *r = nullptr;
};

void pull(Node *t) {
    t-&gt;sum = t-&gt;info;
    t-&gt;siz = 1;
    if (t-&gt;l) {
        t-&gt;sum = t-&gt;l-&gt;sum + t-&gt;sum;
        t-&gt;siz += t-&gt;l-&gt;siz;
    }
    if (t-&gt;r) {
        t-&gt;sum = t-&gt;sum + t-&gt;r-&gt;sum;
        t-&gt;siz += t-&gt;r-&gt;siz;
    }
}

std::pair&amp;#x3C;Node *, Node *&gt; splitAt(Node *t, int p) {
    if (!t) {
        return {t, t};
    }
    if (p &amp;#x3C;= (t-&gt;l ? t-&gt;l-&gt;siz : 0)) {
        auto [l, r] = splitAt(t-&gt;l, p);
        t-&gt;l = r;
        pull(t);
        return {l, t};
    } else {
        auto [l, r] = splitAt(t-&gt;r, p - 1 - (t-&gt;l ? t-&gt;l-&gt;siz : 0));
        t-&gt;r = l;
        pull(t);
        return {t, r};
    }
}

void insertAt(Node *&amp;#x26;t, int p, Node *x) {
    if (!t) {
        t = x;
        return;
    }
    if (x-&gt;w &amp;#x3C; t-&gt;w) {
        auto [l, r] = splitAt(t, p);
        t = x;
        t-&gt;l = l;
        t-&gt;r = r;
        pull(t);
        return;
    }
    if (p &amp;#x3C;= (t-&gt;l ? t-&gt;l-&gt;siz : 0)) {
        insertAt(t-&gt;l, p, x);
    } else {
        insertAt(t-&gt;r, p - 1 - (t-&gt;l ? t-&gt;l-&gt;siz : 0), x);
    }
    pull(t);
}

Node *merge(Node *a, Node *b) {
    if (!a) {
        return b;
    }
    if (!b) {
        return a;
    }

    if (a-&gt;w &amp;#x3C; b-&gt;w) {
        a-&gt;r = merge(a-&gt;r, b);
        pull(a);
        return a;
    } else {
        b-&gt;l = merge(a, b-&gt;l);
        pull(b);
        return b;
    }
}

int query(Node *t, int v) {
    if (!t) {
        return 0;
    }
    if (t-&gt;sum.imp &amp;#x3C; v) {
        return t-&gt;siz;
    }
    int res = query(t-&gt;r, v);
    if (res != (t-&gt;r ? t-&gt;r-&gt;siz : 0)) {
        return res;
    }
    if (t-&gt;info.imp &gt; v) {
        return res;
    }
    return res + 1 + query(t-&gt;l, v);
}

void dfs(Node *t) {
    if (!t) {
        return;
    }
    dfs(t-&gt;l);
    std::cout &amp;#x3C;&amp;#x3C; t-&gt;info.id &amp;#x3C;&amp;#x3C; &quot; &quot;;
    dfs(t-&gt;r);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63162242&quot;&gt;2023-07-31&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Node {
    Node *l = nullptr;
    Node *r = nullptr;
    int cnt = 0;
    int cntnew = 0;
};

Node *add(int l, int r, int x, int isnew) {
    Node *t = new Node;
    t-&gt;cnt = 1;
    t-&gt;cntnew = isnew;
    if (r - l == 1) {
        return t;
    }
    int m = (l + r) / 2;
    if (x &amp;#x3C; m) {
        t-&gt;l = add(l, m, x, isnew);
    } else {
        t-&gt;r = add(m, r, x, isnew);
    }
    return t;
}

struct Info {
    Node *t = nullptr;
    int psum = 0;
    bool rev = false;
};

void pull(Node *t) {
    t-&gt;cnt = (t-&gt;l ? t-&gt;l-&gt;cnt : 0) + (t-&gt;r ? t-&gt;r-&gt;cnt : 0);
    t-&gt;cntnew = (t-&gt;l ? t-&gt;l-&gt;cntnew : 0) + (t-&gt;r ? t-&gt;r-&gt;cntnew : 0);
}

std::pair&amp;#x3C;Node *, Node *&gt; split(Node *t, int l, int r, int x, bool rev) {
    if (!t) {
        return {t, t};
    }
    if (x == 0) {
        return {nullptr, t};
    }
    if (x == t-&gt;cnt) {
        return {t, nullptr};
    }
    if (r - l == 1) {
        Node *t2 = new Node;
        t2-&gt;cnt = t-&gt;cnt - x;
        t-&gt;cnt = x;
        return {t, t2};
    }
    Node *t2 = new Node;
    int m = (l + r) / 2;
    if (!rev) {
        if (t-&gt;l &amp;#x26;&amp;#x26; x &amp;#x3C;= t-&gt;l-&gt;cnt) {
            std::tie(t-&gt;l, t2-&gt;l) = split(t-&gt;l, l, m, x, rev);
            t2-&gt;r = t-&gt;r;
            t-&gt;r = nullptr;
        } else {
            std::tie(t-&gt;r, t2-&gt;r) = split(t-&gt;r, m, r, x - (t-&gt;l ? t-&gt;l-&gt;cnt : 0), rev);
        }
    } else {
        if (t-&gt;r &amp;#x26;&amp;#x26; x &amp;#x3C;= t-&gt;r-&gt;cnt) {
            std::tie(t-&gt;r, t2-&gt;r) = split(t-&gt;r, m, r, x, rev);
            t2-&gt;l = t-&gt;l;
            t-&gt;l = nullptr;
        } else {
            std::tie(t-&gt;l, t2-&gt;l) = split(t-&gt;l, l, m, x - (t-&gt;r ? t-&gt;r-&gt;cnt : 0), rev);
        }
    }
    pull(t);
    pull(t2);
    return {t, t2};
}

Node *merge(Node *t1, Node *t2, int l, int r) {
    if (!t1) {
        return t2;
    }
    if (!t2) {
        return t1;
    }
    if (r - l == 1) {
        t1-&gt;cnt += t2-&gt;cnt;
        t1-&gt;cntnew += t2-&gt;cntnew;
        delete t2;
        return t1;
    }
    int m = (l + r) / 2;
    t1-&gt;l = merge(t1-&gt;l, t2-&gt;l, l, m);
    t1-&gt;r = merge(t1-&gt;r, t2-&gt;r, m, r);
    delete t2;
    pull(t1);
    return t1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;09 - 分数四则运算（Frac）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/598/submission/203186397&quot;&gt;2023-04-23&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;template&amp;#x3C;class T&gt;
struct Frac {
    T num;
    T den;
    Frac(T num_, T den_) : num(num_), den(den_) {
        if (den &amp;#x3C; 0) {
            den = -den;
            num = -num;
        }
    }
    Frac() : Frac(0, 1) {}
    Frac(T num_) : Frac(num_, 1) {}
    explicit operator double() const {
        return 1. * num / den;
    }
    Frac &amp;#x26;operator+=(const Frac &amp;#x26;rhs) {
        num = num * rhs.den + rhs.num * den;
        den *= rhs.den;
        return *this;
    }
    Frac &amp;#x26;operator-=(const Frac &amp;#x26;rhs) {
        num = num * rhs.den - rhs.num * den;
        den *= rhs.den;
        return *this;
    }
    Frac &amp;#x26;operator*=(const Frac &amp;#x26;rhs) {
        num *= rhs.num;
        den *= rhs.den;
        return *this;
    }
    Frac &amp;#x26;operator/=(const Frac &amp;#x26;rhs) {
        num *= rhs.den;
        den *= rhs.num;
        if (den &amp;#x3C; 0) {
            num = -num;
            den = -den;
        }
        return *this;
    }
    friend Frac operator+(Frac lhs, const Frac &amp;#x26;rhs) {
        return lhs += rhs;
    }
    friend Frac operator-(Frac lhs, const Frac &amp;#x26;rhs) {
        return lhs -= rhs;
    }
    friend Frac operator*(Frac lhs, const Frac &amp;#x26;rhs) {
        return lhs *= rhs;
    }
    friend Frac operator/(Frac lhs, const Frac &amp;#x26;rhs) {
        return lhs /= rhs;
    }
    friend Frac operator-(const Frac &amp;#x26;a) {
        return Frac(-a.num, a.den);
    }
    friend bool operator==(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den == rhs.num * lhs.den;
    }
    friend bool operator!=(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den != rhs.num * lhs.den;
    }
    friend bool operator&amp;#x3C;(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den &amp;#x3C; rhs.num * lhs.den;
    }
    friend bool operator&gt;(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den &gt; rhs.num * lhs.den;
    }
    friend bool operator&amp;#x3C;=(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den &amp;#x3C;= rhs.num * lhs.den;
    }
    friend bool operator&gt;=(const Frac &amp;#x26;lhs, const Frac &amp;#x26;rhs) {
        return lhs.num * rhs.den &gt;= rhs.num * lhs.den;
    }
    friend std::ostream &amp;#x26;operator&amp;#x3C;&amp;#x3C;(std::ostream &amp;#x26;os, Frac x) {
        T g = std::gcd(x.num, x.den);
        if (x.den == g) {
            return os &amp;#x3C;&amp;#x3C; x.num / g;
        } else {
            return os &amp;#x3C;&amp;#x3C; x.num / g &amp;#x3C;&amp;#x3C; &quot;/&quot; &amp;#x3C;&amp;#x3C; x.den / g;
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;10 - 线性基（Basis）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1902/submission/235594491&quot;&gt;2023-12-03&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct Basis {
    int a[20] {};
    int t[20] {};

    Basis() {
        std::fill(t, t + 20, -1);
    }

    void add(int x, int y = 1E9) {
        for (int i = 0; i &amp;#x3C; 20; i++) {
            if (x &gt;&gt; i &amp;#x26; 1) {
                if (y &gt; t[i]) {
                    std::swap(a[i], x);
                    std::swap(t[i], y);
                }
                x ^= a[i];
            }
        }
    }

    bool query(int x, int y = 0) {
        for (int i = 0; i &amp;#x3C; 20; i++) {
            if ((x &gt;&gt; i &amp;#x26; 1) &amp;#x26;&amp;#x26; t[i] &gt;= y) {
                x ^= a[i];
            }
        }
        return x == 0;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h1&gt;五、字符串&lt;/h1&gt;
&lt;h2&gt;01 - 马拉车（Manacher）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1827/submission/205865086&quot;&gt;2023-05-14&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;int&gt; manacher(std::string s) {
    std::string t = &quot;#&quot;;
    for (auto c : s) {
        t += c;
        t += &apos;#&apos;;
    }
    int n = t.size();
    std::vector&amp;#x3C;int&gt; r(n);
    for (int i = 0, j = 0; i &amp;#x3C; n; i++) {
        if (2 * j - i &gt;= 0 &amp;#x26;&amp;#x26; j + r[j] &gt; i) {
            r[i] = std::min(r[2 * j - i], j + r[j] - i);
        }
        while (i - r[i] &gt;= 0 &amp;#x26;&amp;#x26; i + r[i] &amp;#x3C; n &amp;#x26;&amp;#x26; t[i - r[i]] == t[i + r[i]]) {
            r[i] += 1;
        }
        if (i + r[i] &gt; j + r[j]) {
            j = i;
        }
    }
    return r;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;02 - Z函数&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=63378373&quot;&gt;2023-08-11&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;std::vector&amp;#x3C;int&gt; zFunction(std::string s) {
    int n = s.size();
    std::vector&amp;#x3C;int&gt; z(n + 1);
    z[0] = n;
    for (int i = 1, j = 1; i &amp;#x3C; n; i++) {
        z[i] = std::max(0, std::min(j + z[j] - i, z[i - j]));
        while (i + z[i] &amp;#x3C; n &amp;#x26;&amp;#x26; s[z[i]] == s[i + z[i]]) {
            z[i]++;
        }
        if (i + z[i] &gt; j + z[j]) {
            j = i;
        }
    }
    return z;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;03 - 后缀数组（SA）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://atcoder.jp/contests/discovery2016-qual/submissions/39727257&quot;&gt;2023-03-14&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct SuffixArray {
    int n;
    std::vector&amp;#x3C;int&gt; sa, rk, lc;
    SuffixArray(const std::string &amp;#x26;s) {
        n = s.length();
        sa.resize(n);
        lc.resize(n - 1);
        rk.resize(n);
        std::iota(sa.begin(), sa.end(), 0);
        std::sort(sa.begin(), sa.end(), [&amp;#x26;](int a, int b) {return s[a] &amp;#x3C; s[b];});
        rk[sa[0]] = 0;
        for (int i = 1; i &amp;#x3C; n; ++i)
            rk[sa[i]] = rk[sa[i - 1]] + (s[sa[i]] != s[sa[i - 1]]);
        int k = 1;
        std::vector&amp;#x3C;int&gt; tmp, cnt(n);
        tmp.reserve(n);
        while (rk[sa[n - 1]] &amp;#x3C; n - 1) {
            tmp.clear();
            for (int i = 0; i &amp;#x3C; k; ++i)
                tmp.push_back(n - k + i);
            for (auto i : sa)
                if (i &gt;= k)
                    tmp.push_back(i - k);
            std::fill(cnt.begin(), cnt.end(), 0);
            for (int i = 0; i &amp;#x3C; n; ++i)
                ++cnt[rk[i]];
            for (int i = 1; i &amp;#x3C; n; ++i)
                cnt[i] += cnt[i - 1];
            for (int i = n - 1; i &gt;= 0; --i)
                sa[--cnt[rk[tmp[i]]]] = tmp[i];
            std::swap(rk, tmp);
            rk[sa[0]] = 0;
            for (int i = 1; i &amp;#x3C; n; ++i)
                rk[sa[i]] = rk[sa[i - 1]] + (tmp[sa[i - 1]] &amp;#x3C; tmp[sa[i]] || sa[i - 1] + k == n || tmp[sa[i - 1] + k] &amp;#x3C; tmp[sa[i] + k]);
            k *= 2;
        }
        for (int i = 0, j = 0; i &amp;#x3C; n; ++i) {
            if (rk[i] == 0) {
                j = 0;
            } else {
                for (j -= j &gt; 0; i + j &amp;#x3C; n &amp;#x26;&amp;#x26; sa[rk[i] - 1] + j &amp;#x3C; n &amp;#x26;&amp;#x26; s[i + j] == s[sa[rk[i] - 1] + j]; )
                    ++j;
                lc[rk[i] - 1] = j;
            }
        }
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04A - 后缀自动机（SuffixAutomaton 旧版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=53409023&amp;#x26;returnHomeType=1&amp;#x26;uid=329687984&quot;&gt;2022-08-17&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct SuffixAutomaton {
    static constexpr int ALPHABET_SIZE = 26, N = 5e5;
    struct Node {
        int len;
        int link;
        int next[ALPHABET_SIZE];
        Node() : len(0), link(0), next{} {}
    } t[2 * N];
    int cntNodes;
    SuffixAutomaton() {
        cntNodes = 1;
        std::fill(t[0].next, t[0].next + ALPHABET_SIZE, 1);
        t[0].len = -1;
    }
    int extend(int p, int c) {
        if (t[p].next[c]) {
            int q = t[p].next[c];
            if (t[q].len == t[p].len + 1)
                return q;
            int r = ++cntNodes;
            t[r].len = t[p].len + 1;
            t[r].link = t[q].link;
            std::copy(t[q].next, t[q].next + ALPHABET_SIZE, t[r].next);
            t[q].link = r;
            while (t[p].next[c] == q) {
                t[p].next[c] = r;
                p = t[p].link;
            }
            return r;
        }
        int cur = ++cntNodes;
        t[cur].len = t[p].len + 1;
        while (!t[p].next[c]) {
            t[p].next[c] = cur;
            p = t[p].link;
        }
        t[cur].link = extend(p, c);
        return cur;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;04B - 后缀自动机（SAM 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://cf.dianhsu.com/gym/104353/submission/207318083&quot;&gt;2023-05-27&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct SAM {
    static constexpr int ALPHABET_SIZE = 26;
    struct Node {
        int len;
        int link;
        std::array&amp;#x3C;int, ALPHABET_SIZE&gt; next;
        Node() : len{}, link{}, next{} {}
    };
    std::vector&amp;#x3C;Node&gt; t;
    SAM() {
        init();
    }
    void init() {
        t.assign(2, Node());
        t[0].next.fill(1);
        t[0].len = -1;
    }
    int newNode() {
        t.emplace_back();
        return t.size() - 1;
    }
    int extend(int p, int c) {
        if (t[p].next[c]) {
            int q = t[p].next[c];
            if (t[q].len == t[p].len + 1) {
                return q;
            }
            int r = newNode();
            t[r].len = t[p].len + 1;
            t[r].link = t[q].link;
            t[r].next = t[q].next;
            t[q].link = r;
            while (t[p].next[c] == q) {
                t[p].next[c] = r;
                p = t[p].link;
            }
            return r;
        }
        int cur = newNode();
        t[cur].len = t[p].len + 1;
        while (!t[p].next[c]) {
            t[p].next[c] = cur;
            p = t[p].link;
        }
        t[cur].link = extend(p, c);
        return cur;
    }
    int extend(int p, char c, char offset = &apos;a&apos;) {
        return extend(p, c - offset);
    }

    int next(int p, int x) {
        return t[p].next[x];
    }

    int next(int p, char c, char offset = &apos;a&apos;) {
        return next(p, c - &apos;a&apos;);
    }

    int link(int p) {
        return t[p].link;
    }

    int len(int p) {
        return t[p].len;
    }

    int size() {
        return t.size();
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;05 - 回文自动机（PAM）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ac.nowcoder.com/acm/contest/view-submission?submissionId=62237107&amp;#x26;returnHomeType=1&amp;#x26;uid=329687984&quot;&gt;2023-05-19&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct PAM {
    static constexpr int ALPHABET_SIZE = 28;
    struct Node {
        int len;
        int link;
        int cnt;
        std::array&amp;#x3C;int, ALPHABET_SIZE&gt; next;
        Node() : len{}, link{}, cnt{}, next{} {}
    };
    std::vector&amp;#x3C;Node&gt; t;
    int suff;
    std::string s;
    PAM() {
        init();
    }
    void init() {
        t.assign(2, Node());
        t[0].len = -1;
        suff = 1;
        s.clear();
    }
    int newNode() {
        t.emplace_back();
        return t.size() - 1;
    }

    bool add(char c, char offset = &apos;a&apos;) {
        int pos = s.size();
        s += c;
        int let = c - offset;
        int cur = suff, curlen = 0;

        while (true) {
            curlen = t[cur].len;
            if (pos - 1 - curlen &gt;= 0 &amp;#x26;&amp;#x26; s[pos - 1 - curlen] == s[pos])
                break;
            cur = t[cur].link;
        }
        if (t[cur].next[let]) {
            suff = t[cur].next[let];
            return false;
        }

        int num = newNode();
        suff = num;
        t[num].len = t[cur].len + 2;
        t[cur].next[let] = num;

        if (t[num].len == 1) {
            t[num].link = 1;
            t[num].cnt = 1;
            return true;
        }

        while (true) {
            cur = t[cur].link;
            curlen = t[cur].len;
            if (pos - 1 - curlen &gt;= 0 &amp;#x26;&amp;#x26; s[pos - 1 - curlen] == s[pos]) {
                t[num].link = t[cur].next[let];
                break;
            }
        }

        t[num].cnt = 1 + t[t[num].link].cnt;

        return true;
    }
};

PAM pam;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06A - AC自动机（AC 旧版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/710/submission/121661266&quot;&gt;2021-07-07&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;constexpr int N = 3e5 + 30, A = 26;

struct Node {
    int fail;
    int sum;
    int next[A];
    Node() : fail(-1), sum(0) {
        std::memset(next, -1, sizeof(next));
    }
} node[N];

int cnt = 0;
int bin[N];
int nBin = 0;

int newNode() {
    int p = nBin &gt; 0 ? bin[--nBin] : cnt++;
    node[p] = Node();
    return p;
}

struct AC {
    std::vector&amp;#x3C;int&gt; x;
    AC(AC &amp;#x26;&amp;#x26;a) : x(std::move(a.x)) {}
    AC(std::vector&amp;#x3C;std::string&gt; s, std::vector&amp;#x3C;int&gt; w) {
        x = {newNode(), newNode()};
        std::fill(node[x[0]].next, node[x[0]].next + A, x[1]);
        node[x[1]].fail = x[0];

        for (int i = 0; i &amp;#x3C; int(s.size()); i++) {
            int p = x[1];
            for (int j = 0; j &amp;#x3C; int(s[i].length()); j++) {
                int c = s[i][j] - &apos;a&apos;;
                if (node[p].next[c] == -1) {
                    int u = newNode();
                    x.push_back(u);
                    node[p].next[c] = u;
                }
                p = node[p].next[c];
            }
            node[p].sum += w[i];
        }

        std::queue&amp;#x3C;int&gt; que;
        que.push(x[1]);
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            node[u].sum += node[node[u].fail].sum;
            for (int c = 0; c &amp;#x3C; A; c++) {
                if (node[u].next[c] == -1) {
                    node[u].next[c] = node[node[u].fail].next[c];
                } else {
                    node[node[u].next[c]].fail = node[node[u].fail].next[c];
                    que.push(node[u].next[c]);
                }
            }
        }
    }
    ~AC() {
        for (auto p : x) {
            bin[nBin++] = p;
        }
    }
    i64 query(const std::string &amp;#x26;s) const {
        i64 ans = 0;
        int p = x[1];
        for (int i = 0; i &amp;#x3C; int(s.length()); i++)  {
            int c = s[i] - &apos;a&apos;;
            p = node[p].next[c];
            ans += node[p].sum;
        }
        return ans;
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;06B - AC自动机（AhoCorasick 新版）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1801/submission/201155712&quot;&gt;2023-04-07&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;struct AhoCorasick {
    static constexpr int ALPHABET = 26;
    struct Node {
        int len;
        int link;
        std::array&amp;#x3C;int, ALPHABET&gt; next;
        Node() : link{}, next{} {}
    };

    std::vector&amp;#x3C;Node&gt; t;

    AhoCorasick() {
        init();
    }

    void init() {
        t.assign(2, Node());
        t[0].next.fill(1);
        t[0].len = -1;
    }

    int newNode() {
        t.emplace_back();
        return t.size() - 1;
    }

    int add(const std::vector&amp;#x3C;int&gt; &amp;#x26;a) {
        int p = 1;
        for (auto x : a) {
            if (t[p].next[x] == 0) {
                t[p].next[x] = newNode();
                t[t[p].next[x]].len = t[p].len + 1;
            }
            p = t[p].next[x];
        }
        return p;
    }

    int add(const std::string &amp;#x26;a, char offset = &apos;a&apos;) {
        std::vector&amp;#x3C;int&gt; b(a.size());
        for (int i = 0; i &amp;#x3C; a.size(); i++) {
            b[i] = a[i] - offset;
        }
        return add(b);
    }

    void work() {
        std::queue&amp;#x3C;int&gt; q;
        q.push(1);

        while (!q.empty()) {
            int x = q.front();
            q.pop();

            for (int i = 0; i &amp;#x3C; ALPHABET; i++) {
                if (t[x].next[i] == 0) {
                    t[x].next[i] = t[t[x].link].next[i];
                } else {
                    t[t[x].next[i]].link = t[t[x].link].next[i];
                    q.push(t[x].next[i]);
                }
            }
        }
    }

    int next(int p, int x) {
        return t[p].next[x];
    }

    int next(int p, char c, char offset = &apos;a&apos;) {
        return next(p, c - &apos;a&apos;);
    }

    int link(int p) {
        return t[p].link;
    }

    int len(int p) {
        return t[p].len;
    }

    int size() {
        return t.size();
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;07 - 随机生成模底 字符串哈希（例题）&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://codeforces.com/contest/1598/submission/160006998&quot;&gt;2022-06-09&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

using i64 = long long;

bool isprime(int n) {
    if (n &amp;#x3C;= 1) {
        return false;
    }
    for (int i = 2; i * i &amp;#x3C;= n; i++) {
        if (n % i == 0) {
            return false;
        }
    }
    return true;
}

int findPrime(int n) {
    while (!isprime(n)) {
        n++;
    }
    return n;
}

using Hash = std::array&amp;#x3C;int, 2&gt;;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());

    const int P = findPrime(rng() % 900000000 + 100000000);

    std::string s, x;
    std::cin &gt;&gt; s &gt;&gt; x;

    int n = s.length();
    int m = x.length();

    std::vector&amp;#x3C;int&gt; h(n + 1), p(n + 1);
    for (int i = 0; i &amp;#x3C; n; i++) {
        h[i + 1] = (10LL * h[i] + s[i] - &apos;0&apos;) % P;
    }
    p[0] = 1;
    for (int i = 0; i &amp;#x3C; n; i++) {
        p[i + 1] = 10LL * p[i] % P;
    }

    auto get = [&amp;#x26;](int l, int r) {
        return (h[r] + 1LL * (P - h[l]) * p[r - l]) % P;
    };

    int px = 0;
    for (auto c : x) {
        px = (10LL * px + c - &apos;0&apos;) % P;
    }

    for (int i = 0; i &amp;#x3C;= n - 2 * (m - 1); i++) {
        if ((get(i, i + m - 1) + get(i + m - 1, i + 2 * m - 2)) % P == px) {
            std::cout &amp;#x3C;&amp;#x3C; i + 1 &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i + m - 1 &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
            std::cout &amp;#x3C;&amp;#x3C; i + m &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i + 2 * m - 2 &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
            return 0;
        }
    }

    std::vector&amp;#x3C;int&gt; z(m + 1), f(n + 1);
    z[0] = m;

    for (int i = 1, j = -1; i &amp;#x3C; m; i++) {
        if (j != -1) {
            z[i] = std::max(0, std::min(j + z[j] - i, z[i - j]));
        }
        while (z[i] + i &amp;#x3C; m &amp;#x26;&amp;#x26; x[z[i]] == x[z[i] + i]) {
            z[i]++;
        }
        if (j == -1 || i + z[i] &gt; j + z[j]) {
            j = i;
        }
    }
    for (int i = 0, j = -1; i &amp;#x3C; n; i++) {
        if (j != -1) {
            f[i] = std::max(0, std::min(j + f[j] - i, z[i - j]));
        }
        while (f[i] + i &amp;#x3C; n &amp;#x26;&amp;#x26; f[i] &amp;#x3C; m &amp;#x26;&amp;#x26; x[f[i]] == s[f[i] + i]) {
            f[i]++;
        }
        if (j == -1 || i + f[i] &gt; j + f[j]) {
            j = i;
        }
    }

    for (int i = 0; i + m &amp;#x3C;= n; i++) {
        int l = std::min(m, f[i]);

        for (auto j : { m - l, m - l - 1 }) {
            if (j &amp;#x3C;= 0) {
                continue;
            }
            if (j &amp;#x3C;= i &amp;#x26;&amp;#x26; (get(i - j, i) + get(i, i + m)) % P == px) {
                std::cout &amp;#x3C;&amp;#x3C; i - j + 1 &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
                std::cout &amp;#x3C;&amp;#x3C; i + 1 &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i + m &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
                return 0;
            }
            if (i + m + j &amp;#x3C;= n &amp;#x26;&amp;#x26; (get(i, i + m) + get(i + m, i + m + j)) % P == px) {
                std::cout &amp;#x3C;&amp;#x3C; i + 1 &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i + m &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
                std::cout &amp;#x3C;&amp;#x3C; i + m + 1 &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; i + m + j &amp;#x3C;&amp;#x3C; &quot;\n&quot;;
                return 0;
            }
        }
    }

    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;本文转自 &lt;a href=&quot;https://www.cnblogs.com/WIDA/p/17633758.html#01b---%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84fenwick-%E6%96%B0%E7%89%88&quot;&gt;https://www.cnblogs.com/WIDA/p/17633758.html#01b---%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84fenwick-%E6%96%B0%E7%89%88&lt;/a&gt;，如有侵权，请联系删除。&lt;/p&gt;</content:encoded><h:img src="/_astro/jiangly-cf-avatar.DEztAaHc.jpg"/><enclosure url="/_astro/jiangly-cf-avatar.DEztAaHc.jpg"/></item><item><title>Educational Codeforces Round 168 (Rated for Div.2)</title><link>https://santisify.top/blog/old/cf1997</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1997</guid><description>codeforces-edu-168(A-C)</description><pubDate>Thu, 08 Aug 2024 23:43:50 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1997/problem/A&quot;&gt;Strong Password&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定字符串，现在让我们添加一个字符，使得字符串的价值最大，对于价值是这样看的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一个字符的价值为&lt;code&gt;2&lt;/code&gt;，&lt;/li&gt;
&lt;li&gt;后面的字符若与前面的字符相同，则价值为&lt;code&gt;1&lt;/code&gt;，否则价值为&lt;code&gt;2&lt;/code&gt;。
让我们输出价值最大的一种情况&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以遍历每一个位置，然后找出在哪个位置插入的价值最大，毕竟 &lt;code&gt;n&lt;/code&gt; 的取值较小，最后再将其替换为与前后位置不相等的字符即可。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	std::string s, t;
	std::cin &gt;&gt; s;

	if(s.size() == 1) {
		std::cout &amp;#x3C;&amp;#x3C; (s[0] == &apos;z&apos; ? &apos;a&apos; : &apos;z&apos;) &amp;#x3C;&amp;#x3C; s[0] &amp;#x3C;&amp;#x3C; endl;
		return;
	}
	int ma = 0;
	for(int i = 0; i &amp;#x3C; s.size(); i++) {
		auto w = s;
		w.insert(w.begin() + i, &apos;.&apos;);
		int res = 2;
		for(int j = 1; j &amp;#x3C; w.size(); j++) {
			if (w[j] == w[j - 1]) {
				res++;
			} else res += 2;
		}
		if (ma &amp;#x3C;= res) {
			ma = res;
			t = w;
		}
	}

	int pos = t.find(&apos;.&apos;);
	int t1 = pos - 1, t2 = pos + 1;
	for(auto i = &apos;a&apos;; i &amp;#x3C;= &apos;z&apos;; i++) {
		if (i != t[t1] &amp;#x26;&amp;#x26; i != t[t2]) {
			t[pos] = i;
			break;
		}
	}
	std::cout &amp;#x3C;&amp;#x3C; t &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1997/problem/B&quot;&gt;Make Three Regions&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个 $2 * n$ 的一个字符矩阵，其中 &lt;code&gt;.&lt;/code&gt; 是开放的，而 &lt;code&gt;X&lt;/code&gt; 是阻塞的，现在让我们判断有几个点可以将这个字符矩阵分为三个联通的区域。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;刚开始的时候，以为是有几个联通的区域，写完 &lt;code&gt;dfs&lt;/code&gt; 后，什么&lt;code&gt;WA1&lt;/code&gt;， 我连 &lt;code&gt;dfs&lt;/code&gt; 都能写错，结果自己是小丑（小插曲）
可以通过给出的图例看出一列只可能有一个点能成为分割点，那么能成为分割点就需要满足四个条件，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$s[0][i] =&apos;.&apos;  &amp;#x26;&amp;#x26; s[1][i] =&apos;.&apos;$&lt;/li&gt;
&lt;li&gt;$s[0][i - 1] \neq s[1][i - 1]$&lt;/li&gt;
&lt;li&gt;$s[0][i+1] \neq s[1][i+1]$&lt;/li&gt;
&lt;li&gt;$s[0][i-1] = s[0][i + 1]$
既然这样，那就简单了&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
	int n = 2, m;
	std::cin &gt;&gt; m;
	std::vector&amp;#x3C;std::string&gt; s(n);
	for(int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; s[i];

	int ans = 0;
	for(int i = 1; i &amp;#x3C; m - 1; i++) {
		bool k = true;
		k &amp;#x26;= (s[0][i] == &apos;.&apos; &amp;#x26;&amp;#x26; s[1][i] == &apos;.&apos;);
		k &amp;#x26;= (s[0][i - 1] != s[1][i - 1]);
		k &amp;#x26;= (s[0][i + 1] != s[1][i + 1]);
		k &amp;#x26;= (s[0][i - 1] == s[0][i + 1]);
		ans += k ? 1 : 0;
	}
	std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr), std::cout.tie(nullptr);
	int Lazy_boy_ = 1;
	std::cin &gt;&gt; Lazy_boy_;
	while (Lazy_boy_--) solve();
	return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1997/problem/C&quot;&gt;Even Positions&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定字符串，让我们输出字符串匹配的&lt;code&gt;()&lt;/code&gt;的最短距离，距离是$pos(&apos;()&apos;) - pos(&apos;(&apos;)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;手指玩玩就行了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include&amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define pii std::pair&amp;#x3C;int ,int&gt;
#define fix(x) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(x)
const int inf = 1e17 + 50, MAX_N = 1e5 + 50, mod = 1e9 + 7;

void solve () {
    int n;
    std::cin &gt;&gt; n;

    std::string s;
    std::cin &gt;&gt; s;

    int pre = 0, ans = 0;
    for(int i = 0; i &amp;#x3C; n; i += 2) {
       if (pre &gt; 0) {
          pre--;
       } else {
          pre++;
       }       ans += pre;
       pre += (s[i + 1] == &apos;(&apos; ? 1 : -1);
       ans += pre;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/7.CwfEP6b0.webp"/><enclosure url="/_astro/7.CwfEP6b0.webp"/></item><item><title>Educational Codeforces Round 161 (Rated for Div.2)</title><link>https://santisify.top/blog/old/cf1922</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1922</guid><description>codeforces-edu-161(A-C)</description><pubDate>Thu, 08 Aug 2024 23:42:58 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1922/problem/A&quot;&gt;Tricky Template&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个数字&lt;code&gt;n&lt;/code&gt;和三个长度为&lt;code&gt;n&lt;/code&gt;的字符串 &lt;code&gt;a&lt;/code&gt;,&lt;code&gt;b&lt;/code&gt;,&lt;code&gt;c&lt;/code&gt;。找一个模板使得字符串&lt;code&gt;a&lt;/code&gt;,&lt;code&gt;b&lt;/code&gt;匹配，而&lt;code&gt;c&lt;/code&gt;不匹配,是否存在这样一个模板.
匹配的定义是:当模板字母为小写时,两个字符串字符相同,为大写时,两个字符不同,这样的两个字符串则匹配&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以直接得出当&lt;code&gt;a&lt;/code&gt;字符串和&lt;code&gt;b&lt;/code&gt;字符串都不等于&lt;code&gt;c&lt;/code&gt;字符串时,就存在这样一个模板使得满足题意&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e18 + 50, pi = 3;
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::string a, b, c;
    std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; c;
    for (int i = 0; i &amp;#x3C; n; i++)
        if (a[i] != c[i] &amp;#x26;&amp;#x26; b[i] != c[i]) {
            std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
            return;
        }
    std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--) solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1922/problem/B&quot;&gt;Forming Triangles&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个长度为&lt;code&gt;n&lt;/code&gt;的一个数组&lt;code&gt;a&lt;/code&gt;,对于&lt;code&gt;a[i]&lt;/code&gt;来说,就是一个长度为&lt;code&gt;2^a[i]&lt;/code&gt;的木棒,现在问:用这些木棒能组成多少个三角形.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;对于一个三角形来说,两边之和大于第三边,两边之差小于第三边,不可能存在两边之和等于第三边,那么我们就可以得到要组成一个三角形就至少需要两条边相等,第三边小于等于这两个边,那么这个问题就成了一个组合数问题&lt;/p&gt;
&lt;p&gt;组合数用&lt;code&gt;C(cnt, m)&lt;/code&gt;来表示,其中&lt;code&gt;cnt&lt;/code&gt;为这个数的总数,&lt;code&gt;m&lt;/code&gt;为我们需要选的个数;
&lt;code&gt;cnt&lt;/code&gt;可以用&lt;code&gt;map&lt;/code&gt;来写,对数组去重,遍历一次数组,&lt;code&gt;s&lt;/code&gt;表示比遍历到当前数字小的个数
即写成&lt;code&gt;ans += C(mp[a[i]], 3) + C(mp[a[i]], 2) * s&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e18 + 50, pi = 3;

int C(int n, int m) {
    if (n &amp;#x3C; m) return 0;
    int ans = 1;
    for (int i = 1; i &amp;#x3C;= m; i++)
        ans = ans * (n - m + i) / i;
    return ans;
}

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n, 0ll);
    std::map&amp;#x3C;int, int&gt; mp;
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i], mp[a[i]]++;
    std::sort(a.begin(), a.end());
    n = std::unique(a.begin(), a.end()) - a.begin();
    int ans = C(mp[a[0]], 3), s = 0;
    for (int i = 1; i &amp;#x3C; n; i++) {
        int t = mp[a[i]];
        s += mp[a[i - 1]];
        ans += C(t, 3) + C(t, 2) * s;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1922/problem/C&quot;&gt;Closest Cities&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;在&lt;code&gt;x&lt;/code&gt;轴上有&lt;code&gt;n&lt;/code&gt;个城市,其位置为&lt;code&gt;a[i]&lt;/code&gt;,并且序列&lt;code&gt;a&lt;/code&gt;按升序排列,保证每个城市只有一个最近的城市
若&lt;code&gt;i&lt;/code&gt;的最近城市是&lt;code&gt;i+1&lt;/code&gt;则花费&lt;code&gt;1&lt;/code&gt;,否则花费&lt;code&gt;|a[i]-a[i+1]|&lt;/code&gt;,现在有&lt;code&gt;q&lt;/code&gt;次询问
问:每次询问城市&lt;code&gt;x&lt;/code&gt;到城市&lt;code&gt;y&lt;/code&gt;的最小花费.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;先分析一下&lt;code&gt;x&amp;#x3C;y&lt;/code&gt;,我们只有一直向右走才会有最小花费,那就需要判断当前城市的最近城市是否为下一个城市.
由于是一直向右走,我么就可以用前缀和求解这个问题.
同理,&lt;code&gt;x&gt;y&lt;/code&gt;时,我们是从右向左走,可以用后缀和求解.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e18 + 50, pi = 3;

void solve() {
    int n, q;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n + 1, 0ll);
    auto s1 = a, s2 = a;
    for (int i = 1; i &amp;#x3C;= n; i++) std::cin &gt;&gt; a[i];
    s1[2] = 1;
    for (int i = 2; i &amp;#x3C; n; i++) {
        if (a[i] - a[i - 1] &gt; a[i + 1] - a[i]) s1[i + 1] = s1[i] + 1;
        else s1[i + 1] = s1[i] + abs(a[i + 1] - a[i]);
    }
    s2[n - 1] = 1;
    for (int i = n - 1; i &gt; 1; i--) {
        if (a[i] - a[i - 1] &gt; a[i + 1] - a[i]) s2[i - 1] = s2[i] + abs(a[i] - a[i - 1]);
        else s2[i - 1] = s2[i] + 1;
    }
//    for (int i = 1; i &amp;#x3C;= n; i++)
//        std::cout &amp;#x3C;&amp;#x3C; s1[i] &amp;#x3C;&amp;#x3C; &apos; &apos;;
//    std::cout &amp;#x3C;&amp;#x3C; endl;
//    for (int i = 1; i &amp;#x3C;= n; i++)
//        std::cout &amp;#x3C;&amp;#x3C; s2[i] &amp;#x3C;&amp;#x3C; &apos; &apos;;
    std::cout &amp;#x3C;&amp;#x3C; endl;
    std::cin &gt;&gt; q;
    while (q--) {
        int x, y;
        std::cin &gt;&gt; x &gt;&gt; y;
        if (x &amp;#x3C; y)
            std::cout &amp;#x3C;&amp;#x3C; s1[y] - s1[x] &amp;#x3C;&amp;#x3C; endl;
        else
            std::cout &amp;#x3C;&amp;#x3C; s2[y] - s2[x] &amp;#x3C;&amp;#x3C; endl;
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/6.DYUaCVYp.webp"/><enclosure url="/_astro/6.DYUaCVYp.webp"/></item><item><title>Educational Codeforces Round 160 (Rated for Div.2)</title><link>https://santisify.top/blog/old/cf1913</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1913</guid><description>codeforces-edu-160(A-C)</description><pubDate>Thu, 08 Aug 2024 23:41:58 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1913/problem/A&quot;&gt;Rating Increas&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个数字,让我们拆分成两个数,这两个数满足以下条件:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;a &amp;#x3C; b&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;两个数没有前缀&lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;问:输出满足条件的数&lt;code&gt;a , b&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;直接暴力循环这个数的位数次,若满足&lt;code&gt;a &amp;#x3C; b&lt;/code&gt;,再判断两个数的位数和是否与拆分前相同.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    int n, cnt = 1, k = 0;
    std::cin &gt;&gt; n;
    int s = n;
    while (s) {
        k++;
        s /= 10;
    }
    int t = k;
    while (k--) {
        int w = n;
        int a = w / cnt, b = w % cnt;
        int x = a, y = b;
        int s1 = 0, s2 = 0;
        while (x) {
            s1++;
            x /= 10;
        }
        while (y) {
            s2++;
            y /= 10;
        }
        if (a &amp;#x3C; b &amp;#x26;&amp;#x26; s1 + s2 == t) {
            std::cout &amp;#x3C;&amp;#x3C; a &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; b &amp;#x3C;&amp;#x3C; endl;
            return;
        }
        cnt *= 10;
    }
    std::cout &amp;#x3C;&amp;#x3C; -1 &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1913/problem/B&quot;&gt;Swap and Delete&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个&lt;code&gt;01&lt;/code&gt;字符串&lt;code&gt;s&lt;/code&gt;,现在有以下操作:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;交换&lt;code&gt;s[i],s[j]&lt;/code&gt;,此操作花费为&lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;删除&lt;code&gt;s[i]&lt;/code&gt;,此操作花费一个金币.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;将修改后的字符串记录为&lt;code&gt;t&lt;/code&gt;.
问:至少花费多少金币,使得&lt;code&gt;t[i] != s[i] (0 &amp;#x3C;= i &amp;#x3C;= t.size())&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以记一下有多少个&lt;code&gt;0&lt;/code&gt; 和多少个&lt;code&gt;1&lt;/code&gt;,
然后我们遍历一次字符串,&lt;code&gt;check&lt;/code&gt;当前&lt;code&gt;0&lt;/code&gt;的个数是否大于&lt;code&gt;1&lt;/code&gt;的总数和当前&lt;code&gt;1&lt;/code&gt;的个数是否大于&lt;code&gt;0&lt;/code&gt;的总数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    int s0 = 0, s1 = 0;
    for (auto i: s)
        s0 += (i == &apos;0&apos;), s1 += (i == &apos;1&apos;);
    int cnt0 = 0, cnt1 = 0, ans = 0;
    for (int i = 0; i &amp;#x3C; (int) s.size(); i++) {
        cnt0 += (s[i] == &apos;0&apos;), cnt1 += (s[i] == &apos;1&apos;);
        if (s0 &gt;= cnt1 &amp;#x26;&amp;#x26; s1 &gt;= cnt0)
            ans = std::max(ans, i + 1);
    }
    std::cout &amp;#x3C;&amp;#x3C; (int) s.size() - ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1913/problem/C&quot;&gt;Game with Multiset&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有两种查询类型:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ADD x&lt;/code&gt;,即在集合中添加&lt;code&gt;2^x&lt;/code&gt;的元素.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET w&lt;/code&gt;,即询问集合中的某子集之和,能否等于&lt;code&gt;w&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;很显然,本题考查位运算,用数组模拟,其中&lt;code&gt;cnt[i]&lt;/code&gt;表示集合中&lt;code&gt;2^i&lt;/code&gt;的元素个数.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; cnt(32, 0ll);
    auto calc = [&amp;#x26;](int x) {
        for (int i = 31; i &gt;= 0; i--) {
            int l = 0, r = cnt[i], s = 0;
            while (l &amp;#x3C;= r) {
                int mid = (l + r + 1) &gt;&gt; 1;
                if (mid * (1 &amp;#x3C;&amp;#x3C; i) &amp;#x3C;= x)
                    s = mid, l = mid + 1;
                else
                    r = mid - 1;
            }
            x -= (1 &amp;#x3C;&amp;#x3C; i) * s;
        }
        std::cout &amp;#x3C;&amp;#x3C; (x == 0 ? &quot;YES&quot; : &quot;NO&quot;) &amp;#x3C;&amp;#x3C; endl;
    };
    while (n--) {
        int t, v;
        std::cin &gt;&gt; t &gt;&gt; v;
        if (t == 1)
            cnt[v]++;
        else
            calc(v);
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
//    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/5.fO04vXCe.webp"/><enclosure url="/_astro/5.fO04vXCe.webp"/></item><item><title>Educational Codeforces Round 159 (Rated for Div.2)</title><link>https://santisify.top/blog/old/cf1902</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1902</guid><description>codeforces-edu-159(A-D)</description><pubDate>Thu, 08 Aug 2024 23:40:53 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1902/problem/A&quot;&gt;Binary Imbalance&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个长度为&lt;code&gt;n&lt;/code&gt;的一个&lt;code&gt;01&lt;/code&gt;字符串，我们执行以下操作：
当&lt;code&gt;s[i]!=s[i+1]&lt;/code&gt;在中间插入&lt;code&gt;0&lt;/code&gt;
问：是否可以实现&lt;code&gt;0&lt;/code&gt;的个数大于&lt;code&gt;1&lt;/code&gt;的个数&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由题意可以明显看出只要有&lt;code&gt;0&lt;/code&gt;就可以实现。下面简单分析下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;的个数大于0，&lt;code&gt;1111110&lt;/code&gt;我们可以在子串&lt;code&gt;10&lt;/code&gt;中间一直插入&lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt;的个数为&lt;code&gt;0&lt;/code&gt;时， &lt;code&gt;11111111&lt;/code&gt;不可能在字符串中插入&lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n;
    std::cin &gt;&gt; n;
    std::string s;
    std::cin &gt;&gt; s;
    for(auto i : s)
        if(i == &apos;0&apos;){
            std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
            return;
        }
        std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1902/problem/B&quot;&gt;Getting Points&lt;/a&gt;(贪心)&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;n&lt;/code&gt;天里面要获得&lt;code&gt;p&lt;/code&gt;分,可以通过两个路径获取分数:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每天上一堂课,可获得&lt;code&gt;i&lt;/code&gt;分.&lt;/li&gt;
&lt;li&gt;进行一次实践,可获得&lt;code&gt;t&lt;/code&gt;分,但是实践==每七天才会有一个==, ==每一天最多可以做两个实践==&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;其中, 一天可以选择休息或者学习, 问最多可以休息多少天.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;可以将所有任务放在最后几天&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;p&gt;(大佬们指点一下)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n, p, L, t;
    std::cin &gt;&gt; n &gt;&gt; p &gt;&gt; L &gt;&gt; t;
    int l = 1, r = n, ans =0 ;
    while(l &amp;#x3C;= r){
        int mid =(l + r)&gt;&gt;1;
        if((n - mid + 1)* L +std::min((n + 6) / 7,(n - mid + 1)* 2 ) * t&gt;= p) ans = mid ,l = mid + 1;
        else r = mid - 1;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans - 1 &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1902/problem/C&quot;&gt;Insert and Equalize&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给你一个整数数组 &lt;code&gt;a[1],a[2],...,a[n]&lt;/code&gt;所有元素都是不同的。&lt;/p&gt;
&lt;p&gt;首先，要求你在这个数组中再插入一个整数 &lt;code&gt;a[n+1]，a[n+1]&lt;/code&gt; 不应等于 a1,a2,...,an。&lt;/p&gt;
&lt;p&gt;然后，你必须使数组中的所有元素相等。一开始，你选择一个==正整数==&lt;code&gt;x(x\&gt;0 )&lt;/code&gt;在一次操作中，你将 &lt;code&gt;x &lt;/code&gt;恰好加到数组的一个元素上。
==注意，所有操作中 x 都是相同的==。
在你选择 &lt;code&gt;a[n+1]&lt;/code&gt;和 &lt;code&gt;x&lt;/code&gt; 之后，使所有元素相等的最小操作次数是多少？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;假设数组&lt;code&gt;a&lt;/code&gt; 中有元素&lt;code&gt;x, y, z &lt;/code&gt;(三者互不相等, 其中 z 最大) , 那么我们就需要找到一个数&lt;code&gt;w&lt;/code&gt;,使得 &lt;code&gt;x+k1*w=z, y+k2*w=z&lt;/code&gt;
显然就可以看出一个性质&lt;code&gt;w=gcd(abs(x-y), abs(y-z))&lt;/code&gt;
就这样我们找到了题目中的&lt;code&gt;x&lt;/code&gt;,接下来, 我们需要找插入的&lt;code&gt;a[n+1]&lt;/code&gt;
令 &lt;code&gt;ma=max(a)&lt;/code&gt;,因为元素互不相等, 我们就需要找插入比&lt;code&gt;ma&lt;/code&gt;大&lt;code&gt;k*w&lt;/code&gt; 和比&lt;code&gt;ma&lt;/code&gt;小&lt;code&gt;k*w&lt;/code&gt;的两个数,
分别重新找出最大值, 并计算所有元素加到&lt;code&gt;ma&lt;/code&gt;的次数
输出两种情况下最小的次数.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a, b;
    std::map&amp;#x3C;int , int&gt; mp;
    for(int i = 0 ; i &amp;#x3C; n ; i ++){
        int x;
        std::cin &gt;&gt; x,a.push_back(x), b.push_back(x), mp[a[i]] = 1;
    }

    int w = unique(a.begin (), a.end()) - a.begin ();
    if(w == 1){
        std::cout &amp;#x3C;&amp;#x3C; 1 &amp;#x3C;&amp;#x3C; endl;
        return ;
    }
    int o = abs(a[1] - a[0]);
    for(int i = 2 ; i &amp;#x3C; n ; i ++)
        o = std::__gcd(abs(a[i] - a[i - 1]), o);
    // std::cout &amp;#x3C;&amp;#x3C; o &amp;#x3C;&amp;#x3C; endl;
    int cnt = 0;
    int k1 = *std::max_element (a.begin (), a.end ());
    while(true){
        cnt ++;
        if(mp[k1 - cnt * o] != 1){
            a.push_back (k1 - cnt * o);
            break;
        }
    }
    k1 = *std::max_element (a.begin (), a.end ());
    int ans1 = 0, ans2 = 0;
    for(int i = 0 ; i &amp;#x3C; (int)a.size(); i ++)
        ans1 += abs(a[i] - k1) / o;
    cnt = 0;
    int k2 = *std::max_element (b.begin (), b.end ());
    while(true){
        cnt ++;
        if(mp[k2 + cnt * o] != 1){
            b.push_back (k2 + cnt * o);
            break;
        }
    }
    k2 = *std::max_element (b.begin (), b.end ());
    for(int i = 0 ; i &amp;#x3C; (int)b.size(); i ++)
        ans2 += abs(a[i] - k2) / o;
    std::cout &amp;#x3C;&amp;#x3C; std::min(ans1, ans2) &amp;#x3C;&amp;#x3C; endl;

}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D &lt;a href=&quot;https://codeforces.com/contest/1902/problem/D&quot;&gt;Robot Queries&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个长度为n 的字符串和q次询问, 机器人开始在&lt;code&gt;(0,0)&lt;/code&gt;
机器人可以执行四条指令：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;U-- 从点&lt;code&gt;(x,y)&lt;/code&gt; 移动到 &lt;code&gt;(x,y+1)&lt;/code&gt; ；&lt;/li&gt;
&lt;li&gt;D-- 从点&lt;code&gt;(x,y)&lt;/code&gt; 移动到 &lt;code&gt;(x,y−1)&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;L--从点 &lt;code&gt;(x,y)&lt;/code&gt; 移动到 &lt;code&gt;(x−1,y)&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;R--从点 &lt;code&gt;(x,y)&lt;/code&gt; 移动到 &lt;code&gt;(x+1,y)&lt;/code&gt;。
每次询问四个数x, y, l, r ,
判断机器人是否访问过点(x, y),但字符串l 到 r 的字串是相反的.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;p&gt;(TLE 13)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    int n, q;
    std::cin &gt;&gt; n &gt;&gt; q;
    std::string s;
    std::cin &gt;&gt; s;
    s = &quot; &quot; + s;
    while(q --){
        int x = 0, y = 0, N, M, l, r;
        std::cin &gt;&gt; N &gt;&gt; M &gt;&gt; l &gt;&gt; r;
        std::string str(s);
        bool f = false;
        reverse (str.begin() + l, str.begin () + r + 1);
        // std::cout &amp;#x3C;&amp;#x3C; str &amp;#x3C;&amp;#x3C; endl;
        for(int i = 1; i &amp;#x3C; (int) str.size() ;i ++){
            if(x == N &amp;#x26;&amp;#x26; y == M){
                std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
                f = true;
                break;
            }
            if(str[i] == &apos;U&apos;)y ++;
            else if(str[i] == &apos;D&apos;) y --;
            else if(str[i] == &apos;L&apos;) x --;
            else x ++;
            if(x == N &amp;#x26;&amp;#x26; y == M){
                std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
                f = true;
                break;
            }
            // std::cout &amp;#x3C;&amp;#x3C; x &amp;#x3C;&amp;#x3C; &quot; &quot; &amp;#x3C;&amp;#x3C; y &amp;#x3C;&amp;#x3C; endl;
        }
        if(!f)
            std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
    }
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    // std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/4.DsS7oGB4.webp"/><enclosure url="/_astro/4.DsS7oGB4.webp"/></item><item><title>Codeforces Round 922 Div2</title><link>https://santisify.top/blog/old/cf1918</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1918</guid><description>codeforces-round-922(A-B)</description><pubDate>Thu, 08 Aug 2024 23:39:47 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1918/problem/A&quot;&gt;Brick Wall&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;砖块大小为&lt;code&gt;1 * k&lt;/code&gt;,砖块可以水平和竖直放置,
现在,我们用这样的砖块砌一堵&lt;code&gt;n * m&lt;/code&gt;的墙, 墙的稳定性为水平砖块数与垂直砖块数之差.
问:最大稳定性是多少&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;为了使墙的稳定性最高,我们可以让所有的砖块水平放置,且砖块的大小为&lt;code&gt;1*2&lt;/code&gt;,这样墙的稳定为$n \times (m / 2)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e16 + 50, MOD = 10007;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n, m;
    std::cin &gt;&gt; n &gt;&gt; m;
    std::cout &amp;#x3C;&amp;#x3C; n * (m / 2) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1918/problem/B&quot;&gt;Minimize Inversions&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;长度为&lt;code&gt;n&lt;/code&gt;的数组&lt;code&gt;a&lt;/code&gt;和&lt;code&gt;b&lt;/code&gt;,由于讨厌倒置($a_{i}&amp;#x3C;a_{j},i &gt;j$)
我们将调整顺序即:交换$a_i,a_j和b_i,b_j$
以使倒置的数较少&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以直接对一个数组排序即可,这样就可以使一个数组没有倒置,使答案最小化.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]const int INF = 1e17 + 50;
[[maybe_unused]] typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;pii&gt; a(n);
    for(int i = 0; i &amp;#x3C; n; i ++)
        std::cin &gt;&gt; a[i].first;
    for(int i = 0; i &amp;#x3C; n; i ++)
        std::cin &gt;&gt; a[i].second;
    std::sort(a.begin(), a.end());
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cout &amp;#x3C;&amp;#x3C; a[i].first &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n - 1];
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cout &amp;#x3C;&amp;#x3C; a[i].second &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n - 1];
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/2.CC9RmHu9.webp"/><enclosure url="/_astro/2.CC9RmHu9.webp"/></item><item><title>Codeforces Round 916 Div3</title><link>https://santisify.top/blog/old/cf1914</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1914</guid><description>codeforces-round-916(A-D)</description><pubDate>Thu, 08 Aug 2024 23:38:48 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1914/problem/A&quot;&gt;Problemsolving Log&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个整数&lt;code&gt;n&lt;/code&gt;,字符串&lt;code&gt;s&lt;/code&gt;,字符串中&lt;code&gt;s[i]&lt;/code&gt;表示第&lt;code&gt;i&lt;/code&gt;分钟解决第&lt;code&gt;s[i]&lt;/code&gt;题.
问题&lt;code&gt;A&lt;/code&gt;需要&lt;code&gt;1&lt;/code&gt;分钟解决,问题&lt;code&gt;B&lt;/code&gt;需要&lt;code&gt;2&lt;/code&gt;分钟解决,以此类推.&lt;/p&gt;
&lt;p&gt;问:可以解决多少题?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;遍历字符串,统计问题&lt;code&gt;A -- Z&lt;/code&gt;用了多少时间解决.
最后在遍历数组,判断问题&lt;code&gt;A -- Z&lt;/code&gt;是否满足解决时间.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::string s;
    std::cin &gt;&gt; s;
    std::vector&amp;#x3C;int&gt; a(26, 0);
    for (auto i: s)
        a[i - &apos;A&apos;]++;
    int cnt = 0;
    for (int i = 0; i &amp;#x3C; 26; i++)
        if (a[i] &gt;= i + 1)
            cnt++;
    std::cout &amp;#x3C;&amp;#x3C; cnt &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1914/problem/B&quot;&gt;Preparing for the Contest&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给两个整数&lt;code&gt;n, k (0 &amp;#x3C;= k &amp;#x3C;= n - 1)&lt;/code&gt;
问:打印出&lt;code&gt;a[i + 1] &gt; a[i](0&amp;#x3C;= i &amp;#x3C; n - 1)&lt;/code&gt;的次数等于&lt;code&gt;k&lt;/code&gt;的方案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;打个比方:
&lt;code&gt;n == 6, k == 2&lt;/code&gt;, 我们有这样一个数组&lt;code&gt;[1, 2, 3, 4, 5, 6]&lt;/code&gt;
现在将数组重新排序,排序后要满足&lt;code&gt;a[i + 1] &gt; a[i](0&amp;#x3C;= i &amp;#x3C; n - 1)&lt;/code&gt;的次数等于&lt;code&gt;k&lt;/code&gt;.
我们可以将数组后面&lt;code&gt;k + 1&lt;/code&gt;个数放在前面,即&lt;code&gt;[4, 5, 6, 1, 2, 3]&lt;/code&gt;
多举几个例子就可以发现上述规律.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n, 0ll);
    std::iota(a.begin(), a.end(), 1ll);
    for (int i = n - k - 1; i &amp;#x3C; n; i++)
        std::cout &amp;#x3C;&amp;#x3C; a[i] &amp;#x3C;&amp;#x3C; &quot; &quot;;
    for (int i = n - k - 2; i &gt;= 0; i--)
        std::cout &amp;#x3C;&amp;#x3C; a[i] &amp;#x3C;&amp;#x3C; &quot; &quot;;
    std::cout &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1914/problem/C&quot;&gt;Quests&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有&lt;code&gt;n&lt;/code&gt;个任务,每个任务完成后对应两个值&lt;code&gt;a[i]&lt;/code&gt;和&lt;code&gt;b[i]&lt;/code&gt;,首次完成第&lt;code&gt;i&lt;/code&gt;个任务时,可获得&lt;code&gt;a[i]&lt;/code&gt;分,若此后再完成该任务可获得&lt;code&gt;b[i]&lt;/code&gt;分
问:现在,可以完成&lt;code&gt;k&lt;/code&gt;个任务,可获得的最大分数是多少?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;枚举走到哪一个位置，然后记录前面的b[i]最大值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;
#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n + 1, 0ll), b(n + 1, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++)
        std::cin &gt;&gt; a[i];
    for (int i = 0; i &amp;#x3C; n; i++)
        std::cin &gt;&gt; b[i];
    int s = 0, ma = 0, ans = 0;
    for (int i = 0; i &amp;#x3C; std::min(n, k); i++) {
        s += a[i];
        ma = std::max(ma, b[i]);
        ans = std::max(ans, s + (k - i - 1) * ma);
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D &lt;a href=&quot;https://codeforces.com/contest/1914/problem/D&quot;&gt;Three Activities&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给出一个&lt;code&gt;n&lt;/code&gt;,并且给出这&lt;code&gt;n&lt;/code&gt;天参加三项活动的人数&lt;code&gt;a[i], b[i], c[i]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;问:最多能有多少人参加这三项活动,并且参加这三项不在同一天.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们只需要模拟一下,但是这个模拟需要优化一下.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n, 0ll), b(n, 0ll), c(n, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++)std::cin &gt;&gt; a[i];
    for (int i = 0; i &amp;#x3C; n; i++)std::cin &gt;&gt; b[i];
    for (int i = 0; i &amp;#x3C; n; i++)std::cin &gt;&gt; c[i];
    std::vector&amp;#x3C;int&gt; x(n, 0ll);
    std::iota(x.begin(), x.end(), 0ll);
    auto y = x, z = x;
    std::sort(x.begin(), x.end(), [&amp;#x26;](int aa, int bb) { return a[aa] &gt; a[bb]; });
    std::sort(y.begin(), y.end(), [&amp;#x26;](int aa, int bb) { return b[aa] &gt; b[bb]; });
    std::sort(z.begin(), z.end(), [&amp;#x26;](int aa, int bb) { return c[aa] &gt; c[bb]; });
    int w = std::min({n, 100ll}), ans = 0ll;
    for (int i = 0; i &amp;#x3C; w; i++)
        for (int j = 0; j &amp;#x3C; w; j++)
            for (int k = 0; k &amp;#x3C; w; k++)
                if (x[i] != y[j] &amp;#x26;&amp;#x26; x[i] != z[k] &amp;#x26;&amp;#x26; y[j] != z[k])
                    ans = std::max(a[x[i]] + b[y[j]] + c[z[k]], ans);
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/1.BcdCEwMr.webp"/><enclosure url="/_astro/1.BcdCEwMr.webp"/></item><item><title>Codeforces Round 914 Div2</title><link>https://santisify.top/blog/old/cf1904</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1904</guid><description>codeforces-round-912(A-C)</description><pubDate>Thu, 08 Aug 2024 23:36:20 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1904/problem/A&quot;&gt;Forked!&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定王后和国王的位置, 马可以先朝一个方向走&lt;code&gt;a&lt;/code&gt;步,再朝另一个方向走&lt;code&gt;b&lt;/code&gt;步
问:马有多少个位置可以同时走到皇后和国王&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;就无脑遍历一下马能走到国王和皇后的位置
然后再判断下有没有相同的位置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 1e9 + 50;

int dx[4] = {-1, 1, -1, 1}, dy[4] = {-1, -1, 1, 1};

void solve() {
    int x1, x2, y1, y2, a, b;
    std::cin &gt;&gt; a &gt;&gt; b &gt;&gt; x1 &gt;&gt; y1 &gt;&gt; x2 &gt;&gt; y2;
    std::set&amp;#x3C;std::pair&amp;#x3C;int ,int&gt;&gt; s1, s2;
    for(int i = 0 ; i &amp;#x3C; 4 ; i++){
        s1.insert({x1+dx[i]*a, y1+dy[i]*b});
        s1.insert({x1+dx[i]*b, y1+dy[i]*a});
        s2.insert({x2+dx[i]*a, y2+dy[i]*b});
        s2.insert({x2+dx[i]*b, y2+dy[i]*a});
    }
    int cnt = 0;
    for(auto i : s1){
        if(s2.find (i) != s2.end())
            cnt ++;
    }
    std::cout &amp;#x3C;&amp;#x3C; cnt &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1904/problem/B&quot;&gt;Collecting Game&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个数组&lt;code&gt;a&lt;/code&gt;,对于每一个元素,我们都会有一个初始值&lt;code&gt;w = a[i]  (0 &amp;#x3C;= i &amp;#x3C; n)&lt;/code&gt;只要&lt;code&gt;w&lt;/code&gt;大于或等于数组中的某个元素,&lt;code&gt;w = w + a[k]&lt;/code&gt;并且就会把这个数删除掉.&lt;/p&gt;
&lt;p&gt;问: 对于每个元素,至多可以删除多少元素?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于需要最大化删除个数,我们可以先对数组升序排序,这样对于&lt;code&gt;i(0 &amp;#x3C;= i &amp;#x3C; n)&lt;/code&gt; 就可以将&lt;code&gt;0 ~ i-1&lt;/code&gt;的所有数删除掉,然后再考虑后面的.&lt;/p&gt;
&lt;p&gt;就这样模拟下过程就完事儿了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;p&gt;(提交的一次TLE的代码)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    pii a[n];
    for (int i = 0; i &amp;#x3C; n; i++)
        std::cin &gt;&gt; a[i].first, a[i].second = i;
    std::sort(a, a + n);
    std::vector&amp;#x3C;int&gt; s(n, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++) {
        if (i == 0)
            s[i] = a[i].first;
        else
            s[i] = s[i - 1] + a[i].first;
    }
    std::vector&amp;#x3C;int&gt; ans(n, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++) {
        int t = s[i], j = i + 1;
        while (j &amp;#x3C; n &amp;#x26;&amp;#x26; t &gt;= a[j].first)
            t += a[j++].first;
        ans[i] = j - 1;
    }
    for (int i = 0; i &amp;#x3C; n; i++)
        a[i].first = ans[i];
    std::sort(a, a + n, [&amp;#x26;](pii aa, pii bb) {
        return aa.second &amp;#x3C; bb.second;
    });
    for(int i = 0 ; i &amp;#x3C; n ; i ++){
        std::cout &amp;#x3C;&amp;#x3C; a[i].first &amp;#x3C;&amp;#x3C; &quot; &quot;;
    }
    std::cout &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(AC代码)&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
[[maybe_unused]] const int INF = 1e9 + 50;

typedef std::pair&amp;#x3C;int, int&gt; pii;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    pii a[n + 1];
    for (int i = 0; i &amp;#x3C; n; i++) {
        std::cin &gt;&gt; a[i].first;
        a[i].second = i;
    }
    std::sort(a, a + n);
    std::vector&amp;#x3C;int&gt; b(n, 0ll), c(n, 0ll), d(n, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++) {
        b[i] = a[i].first;
        if (i == 0)
            c[i] = b[i];
        else
            c[i] = c[i + 1] + b[i];
    }
    for (int i = 0; i &amp;#x3C; n; i++) {
        int t = c[i];
        int k = t;
        while (true) {
            int w = std::upper_bound(b.begin(), b.end(), t) - b.begin();
            if (w == n) {
                d[a[i].second] = n - 1;
                break;
            } else {
                if (c[w - 1] == k) {
                    d[a[i].second] = w - 1;
                    break;
                } else {
                    k = c[w - 1];
                    t = c[w - 1];
                }
            }
        }
    }

    for (int i = 0; i &amp;#x3C; n; i++)
        std::cout &amp;#x3C;&amp;#x3C; d[i] &amp;#x3C;&amp;#x3C; &quot; &quot;;
    std::cout &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1904/problem/C&quot;&gt;Array Game&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个数组&lt;code&gt;a&lt;/code&gt;,有&lt;code&gt;k&lt;/code&gt;次操作,每次操作选一个&lt;code&gt;(i, j) (0 &amp;#x3C;= i &amp;#x3C; j &amp;#x3C; n)&lt;/code&gt; ,将&lt;code&gt;|a[j] - a[i]|&lt;/code&gt;放在数组的足以后方.&lt;/p&gt;
&lt;p&gt;问:&lt;code&gt;k&lt;/code&gt;次操作后得到的数组最小的数为多少?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;首先,可以考虑到&lt;code&gt;k&gt;=3&lt;/code&gt;时,我们可以先选两次相同的&lt;code&gt;(i, j)&lt;/code&gt;,然后再选新加入的这两个,这样就可以得到&lt;code&gt;0&lt;/code&gt;了`&lt;/p&gt;
&lt;p&gt;然后再是&lt;code&gt;k == 1&lt;/code&gt;时, 我们想让答案最小化,我们只能先将数组排序,然后再找相邻的两个的的差值,再到最小值后,答案还不是最优值, 所以还要与原数组最小值比较.&lt;/p&gt;
&lt;p&gt;最后, 再是 &lt;code&gt;k == 2&lt;/code&gt;时, 题目中明确告诉&lt;code&gt;n^2 &amp;#x3C; 4e6&lt;/code&gt;,这就是让我们暴力循环,我们可以先将&lt;code&gt;k == 1&lt;/code&gt;时的最小值记录下来,然后再暴力&lt;code&gt;n^2&lt;/code&gt;跑一遍数组,再与之前的比较一下,最后输出答案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve() {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a;
    for (int i = 0; i &amp;#x3C; n; i++) {
        int x;
        std::cin &gt;&gt; x;
        a.push_back(x);
    }
    if (k &gt;= 3) {
        std::cout &amp;#x3C;&amp;#x3C; 0 &amp;#x3C;&amp;#x3C; endl;
        return;
    }
    std::sort(a.begin(), a.end());
    auto calc = [&amp;#x26;]() {//相当于处理了一次
        std::sort(a.begin(), a.end());
        int ans = a[0];
        for (int i = 1; i &amp;#x3C; (int) a.size(); i++) {
            ans = std::min(ans, a[i] - a[i - 1]);
        }
        return ans;
    };

    int ans = calc();
    if (k == 2) {
        for (int i = 0; i &amp;#x3C; n; i++) {
            for (int j = i + 1; j &amp;#x3C; n; j++) {
                int w = a[j] - a[i];
                int p = std::lower_bound(a.begin(), a.end(), w) - a.begin();
                if (p != n - 1)
                    ans = std::min(ans, a[p] - w);
                if (p != 0)
                    ans = std::min(ans, w - a[p - 1]);
            }
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/13.Bpx9-52Q.webp"/><enclosure url="/_astro/13.Bpx9-52Q.webp"/></item><item><title>Codeforces Round 913 Div3</title><link>https://santisify.top/blog/old/cf1907</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1907</guid><description>codeforces-round-913(A-D)</description><pubDate>Wed, 07 Aug 2024 17:11:13 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1907/problem/A&quot;&gt;Rook&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给一个国际象棋棋盘,有&lt;code&gt;t&lt;/code&gt;次询问,每次询问给定一个棋子坐标&lt;code&gt;s&lt;/code&gt; 例如 &lt;code&gt;d4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;问: 输出这个棋子上下左右四个方向的坐标&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;两个&lt;code&gt;for&lt;/code&gt;循环暴力求解&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve(){
    std::string s;
    std::cin &gt;&gt; s;
    for(int i = 1; i &amp;#x3C;= 8 ; i ++)//枚举当前列
        if(i != s[1] - &apos;0&apos;)
            std::cout &amp;#x3C;&amp;#x3C; s[0] &amp;#x3C;&amp;#x3C; i &amp;#x3C;&amp;#x3C; endl;

    for(int i = 0; i &amp;#x3C; 8 ; i ++)//枚举当前行
        if(i + &apos;a&apos; != s[0])
            std::cout &amp;#x3C;&amp;#x3C; (char)(i + &apos;a&apos;) &amp;#x3C;&amp;#x3C; s[1] &amp;#x3C;&amp;#x3C; endl;
}

signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1907/problem/B&quot;&gt;YetnotherrokenKeoard&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有&lt;code&gt;t&lt;/code&gt;次询问,每次询问会给定一个字符串&lt;code&gt;s&lt;/code&gt;,
我们要敲击键盘拼接出这个字符串,但是存在一些规则:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;每次敲击&lt;code&gt;b&lt;/code&gt;就会将位于这个&lt;code&gt;b&lt;/code&gt;左边存在小写字母,那么就将距离&lt;code&gt;b&lt;/code&gt;最近的一个删除,&lt;/li&gt;
&lt;li&gt;同理,当敲击大写字母时,就会删除这个&lt;code&gt;B&lt;/code&gt;左边最近的一个大写字母.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;问: 最后会组成一个怎样的字符串.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;这个题由于数据量比较大,就不要尝试双重循环去删除字符了
我们可以发现一个规律,我们只删除当前字符前大小写形式相同的字符,并且只能删除一次,而且
是删除距离最近的,
这就有点像堆栈(后进先出),那我们就可以用栈来模拟这个过程
我们可以给每个字符做个标记,即创建一个和字符串大小相同的bool数组
若为&lt;code&gt;b&lt;/code&gt;或&lt;code&gt;B&lt;/code&gt;或被删除的字符标记为&lt;code&gt;false&lt;/code&gt;,否则为true&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve() {
    std::string s;
    std::cin &gt;&gt; s;
    std::vector&amp;#x3C;bool&gt; f((int) s.size(), true);
    std::stack&amp;#x3C;int&gt; a, b;
    for (int i = 0; i &amp;#x3C; (int) s.size(); i++) {
        if (s[i] == &apos;b&apos; || s[i] == &apos;B&apos;) {
            f[i] = false;
            if (isupper(s[i]) &amp;#x26;&amp;#x26; !b.empty()){
                f[b.top()] = false;
                b.pop();
            }
            else if(islower(s[i]) &amp;#x26;&amp;#x26; !a.empty()){
                f[a.top()] = false;
                a.pop();
            }
        } else {
            if(islower(s[i]))
                a.push(i);
            else
                b.push(i);
        }
    }
    while (!a.empty())
        a.pop();
    while (!b.empty())
        b.pop();
    for (int i = 0; i &amp;#x3C; (int) s.size(); i++)
        if (f[i])
            std::cout &amp;#x3C;&amp;#x3C; s[i];
    std::cout &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1907/problem/C&quot;&gt;Removal of Unattractive Pairs&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有&lt;code&gt;t&lt;/code&gt;次询问,每次询问给出一个长度为&lt;code&gt;n&lt;/code&gt;的字符串,字符串两个字符不同则可以删除这两个字符
问: 字符串最短有多长.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;用手玩玩就&lt;code&gt;ok&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::string s;
    std::cin &gt;&gt; s;
    std::vector&amp;#x3C;int&gt; a(26, 0ll);
    for(auto i : s)
        a[i - &apos;a&apos;] ++;
    int ma = *std::max_element(a.begin (), a.end());
    if(ma * 2 &amp;#x3C;= n)
        std::cout &amp;#x3C;&amp;#x3C; n % 2 &amp;#x3C;&amp;#x3C; endl;
    else
        std::cout &amp;#x3C;&amp;#x3C; n - 2 * (n - ma) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D &lt;a href=&quot;https://codeforces.com/contest/1907/problem/C&quot;&gt;Jumping Through Segments&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;有&lt;code&gt;t&lt;/code&gt;次询问,每次询问会给&lt;code&gt;n&lt;/code&gt;个&lt;code&gt;L, R&lt;/code&gt;,其中第 &lt;code&gt;i&lt;/code&gt; 段从坐标为&lt;code&gt;L[i]&lt;/code&gt;的点开始,到坐标为&lt;code&gt;R[i]&lt;/code&gt;的点结束。
玩家从坐标为 0 的点开始通关。在一次移动中，他们可以移动到距离不超过 k 的任意一点。
在第&lt;code&gt;i&lt;/code&gt;次移动后，玩家必须落在第&lt;code&gt;i&lt;/code&gt;段之内，即在坐标&lt;code&gt;x&lt;/code&gt;处，使得 &lt;code&gt;L[i]≤x≤R[i]&lt;/code&gt;。
这意味着,每次移动都必须在&lt;code&gt;L[i] ~ R[i]&lt;/code&gt;
如果玩家按照上述规则到达了第 &lt;code&gt;n&lt;/code&gt;个段落，那么这一关就算完成了。
为了不希望这个关卡太简单，所以要求确定可以完成这个关卡的最小整数&lt;code&gt;k&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;核心思想就是&lt;strong&gt;二分答案&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int INF = 0x3f3f3f3f;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; L(n, 0ll), R(n, 0ll);
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cin &gt;&gt; L[i] &gt;&gt; R[i];
    int l = 0, r = 1e16 + 50;
    auto check = [&amp;#x26;] (int x){
        int ma = 0, mi = 0;
        for(int i = 0 ; i &amp;#x3C; n ; i ++){
            ma = std::min (ma + x, INF);
            mi = std::max (mi - x, 0ll);
            mi = std::max(mi, L[i]);
            ma = std::min(ma, R[i]);
            if(mi &gt; ma)
                return false;
        }
        return true;
    };
    while(l &amp;#x3C; r){
        int mid = (l + r) &gt;&gt; 1;
        if(check (mid)) r = mid;
        else l = mid + 1;
    }
    std::cout &amp;#x3C;&amp;#x3C; r &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/12.DXs13duw.webp"/><enclosure url="/_astro/12.DXs13duw.webp"/></item><item><title>Codeforces Round 912 Div2</title><link>https://santisify.top/blog/old/cf1903</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1903</guid><description>codeforces-round-912(A-D1)</description><pubDate>Wed, 07 Aug 2024 17:07:28 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1903/problem/A&quot;&gt;Halloumi Boxes&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个数组A,我们可以对数组惊醒多次操作,操作如下:
我们可以将数组中的某一段倒置,但是长度不能超过K,例如:反转子数组意味着选择两个索引i和j(其中 1 &amp;#x3C;= i &amp;#x3C;= j &amp;#x3C;= n )
并将数组 $a_1,a_2,\cdots,a_n$ 改为 $a_1,a_2,\cdots,a_{i−1},a_{j},a_{j−1},\cdots,a_{i},a_{j+1},…,a_{n-1},a_n \quad (j − i + 1 \le k )$ 。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;分析&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于可以操作多次,那么我们可以判断下k是否为1:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;若k = 1时, 我们只能反转一个元素,显然是无效的, 我们就只需要判断数组是否为有序&lt;/li&gt;
&lt;li&gt;若k &gt; 1时,显然是可行的&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve () {
    int n, k;
    std::cin &gt;&gt; n &gt;&gt; k;
    std::vector&amp;#x3C;int&gt; a(n, 0), b(n, 0);
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cin &gt;&gt; a[i], b[i] = a[i];

    std::sort(b.begin (), b.end ());
    bool f = true;
    for(int i = 0 ; i &amp;#x3C; n ; i ++){
        if(a[i] != b[i]){
            f = false;
            break;
        }
    }
    if(f)
        std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
    else {
        if(k &gt; 1)
            std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
        else
            std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
    }
}


signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1903/problem/B&quot;&gt;StORage room&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个数&lt;code&gt;n&lt;/code&gt;,和一个&lt;code&gt;n*n&lt;/code&gt;的数组&lt;code&gt;M&lt;/code&gt;,数组$M_{i,j}$
表示为:$M_{i,j} = \begin{cases} a_i|a_j,(i \not= j)\\ 0, (i == j)\end{cases}(M_{i,j} &amp;#x3C; 2 ^{30})$&lt;/p&gt;
&lt;p&gt;让我们判断是否存在这样的一个数组a满足上式,若存在输出YES和数组a
否则输出NO&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;分析&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;现在我有两个数&lt;code&gt;x, y&lt;/code&gt;,如果我将这两个数进行或运算后&lt;code&gt;(w = x | y)&lt;/code&gt;, 在二进制状态下&lt;code&gt;x&lt;/code&gt;和&lt;code&gt;y&lt;/code&gt;在某一位上有一个为&lt;code&gt;1&lt;/code&gt;,则该位为&lt;code&gt;1&lt;/code&gt;通过这个我们可以发现在$M_i$ 中,$M_{i,0} = a_i | a_0, M_{i,1} = a_i | a_1, ........, M_{i,n - 1} = a_i | a_{n - 1}$ , 我们可以通过与运算将$a_i$
计算出来, 但是在运算时我们需要排除$M_{i,j}(i==j)$;
在计算完后我们可以遍历一次M数组,判断$M_{i,j}=a_i|a_j(i \not= j)$&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;参考代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve () {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n, 0);
    std::vector&amp;#x3C;std::vector&amp;#x3C;int&gt; &gt; m(n, std::vector&amp;#x3C;int&gt; (n, 0));
    for(int i = 0 ; i &amp;#x3C; n ; i ++){
        int x = -1;
        for(int j = 0;j &amp;#x3C; n;j ++){
            std::cin &gt;&gt; m[i][j];
            if(i != j){
                if(x == -1)
                    x = m[i][j];
                x &amp;#x26;= m[i][j];
            }
        }
        a[i] = x;
    }
    if(n == 1){//特殊情况,可任意输出一个数
        std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl &amp;#x3C;&amp;#x3C; 1 &amp;#x3C;&amp;#x3C; endl;
        return ;
    }
    auto check = [&amp;#x26;] (){
        for(int i = 0 ; i &amp;#x3C; n ; i ++){
            for(int j = 0 ; j &amp;#x3C; n ; j ++){
                int x = a[i] | a[j];
                if(m[i][j] != x &amp;#x26;&amp;#x26; i != j){
                    return false;
                }
            }
        }
        return true;
    };
    if(check()){
        std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
        for(int i = 0 ; i &amp;#x3C; n ; i ++)
            std::cout &amp;#x3C;&amp;#x3C; a[i] &amp;#x3C;&amp;#x3C; &quot; &quot;;
        std::cout &amp;#x3C;&amp;#x3C; endl;
    }
    else
        std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C;endl;
}


signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1903/problem/C&quot;&gt;Theofanis&apos; Nightmare&lt;/a&gt;(贪心)&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定一个数组&lt;code&gt;a&lt;/code&gt;,大小为&lt;code&gt;n&lt;/code&gt;,现在将数组&lt;code&gt;a&lt;/code&gt;分割成几个非空子数组,并且保证每个元素只在一个一个子数组中,例如，数组 &lt;code&gt;[1,−3,7,−6,2,5]&lt;/code&gt;可以划分为 &lt;code&gt;[1][−3,7][−6,2][5]&lt;/code&gt;。
这种分割的值等于$\sum_{i=1}^k i*sum_i$
，其中&lt;code&gt;k&lt;/code&gt;是我们将数组分割成的子数组的个数，$sum_i$
是第&lt;code&gt;i&lt;/code&gt;个子数组的和。
这个数组的值为$[1][−3,7][−6,2][5]=1\times 1+2\times (−3+7)+3\times (−6+2)+4\times5=17$
现在让我们求分割的最大值为多少?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;分析&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;先考虑每个子段的数字贡献，i* sum_i也可以转化为该子段中每个数字被加上了i次。那么就可以把乘法转化为加法。&lt;/p&gt;
&lt;p&gt;然后考虑怎么划分子段最优，如果从前往后考虑，很难判断是否该将当前数字划分为一个新子段的起点。
因此，需要从后往前遍历，统计i∼n之间的数字总和，为了使答案尽可能大，那么只要当前数字总和大于等于0，就可以将当前位置划分给一个新的子段起点。&lt;/p&gt;
&lt;p&gt;此时，划分出一个新的起点后，那么后面所有的数字均需要再被加上一次，不难发现，此时要加上的就是维护的数字总和。&lt;/p&gt;
&lt;p&gt;由于第一个元素也可能被划分到一个新的子段中，为了避免重复计算，当遍历到第一个元素时，必须将当前元素视为子段起点，加上维护的数字总和。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve () {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n, 0);
    for(int i = 0 ; i &amp;#x3C; n ; i ++)
        std::cin &gt;&gt; a[i];
    int ans = 0, w = 0;
    for(int i = n - 1; i &gt;= 0 ; i --){
        w += a[i];
        if(i == 0 || w &gt; 0)
            ans += w;
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}


signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy = 1;
    std::cin &gt;&gt; Lazy_boy;
    while (Lazy_boy--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;

void solve () {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n + 1, 0ll), s(n + 1, 0ll);
    for(int i = 1 ; i &amp;#x3C;= n ; i ++)
        std::cin &gt;&gt; a[i], s[i] = s[i - 1] + a[i];
    int ans = 0, w = 0;
    for(int i = 1; i &amp;#x3C;= n ; i ++){
        if(i == 1 || s[n] - s[i - 1] &gt;= 0)
            w ++;
        ans += w * a[i];
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}


signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;D1 &lt;a href=&quot;https://codeforces.com/contest/1903/problem/D1&quot;&gt;Maximum And Queries (easy version)&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给出一个长度为n的数组a，并进行q次询问，每次询问为：
你可以进行&lt;code&gt;k&lt;/code&gt;次操作，每次从数组a中选择一个元素，让这个元素 &lt;code&gt;+ 1&lt;/code&gt;。
问：经过&lt;code&gt;q&lt;/code&gt;次操作后,$a_1,a_2,.....,a_n$的与的最大值是多少
注：每次询问都是独立的，不会保留前面询问的操作结果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;分析&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;由于每次询问都是独立的，那么修改不能在原数组上进行，需要将原数组元素复制到其他数组中再进行操作。
题目数据规定了$n\times q≤10^5$，那么可以认为最大的数据就是对长度为$10^5$的数组进行一次询问。由于给出的$k≤10^{18}$ ，那么当数组中只有一个元素时，最大可能的结果为$10^{18}+10^6≈2^{60}$
，因此需要一个大于&lt;code&gt;60&lt;/code&gt;的数组记录与运算后的结果每位二进制数是多少。
对于每次询问，从二进制高位开始往低位进行遍历，每次检查当前剩余的k是否还能将数组中所有数的当前二进制位修改为1
如果可以，进行修改，并记录在答案数组中，如果不行，继续遍历更低的二进制位。
结束修改后，将数组中记录的信息转化为十进制数即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;本题数据较大，需要注意使用左移运算需要使用1ll将1转化为long long类型再进行运算，计算花费时也要考虑如果超过操作次数就该退出检查，避免数据溢出。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
const int N = 1e5 + 5;

int a[N], b[N], ans[105];
int n, q;

int getCost(int x, int k) {
    int cost = 0;
    for (int j = 1; j &amp;#x3C;= n; j++) {
        if ((b[j] &amp;#x26; (1ll &amp;#x3C;&amp;#x3C; x)) == 0) {
            //使用位运算计算将b[j]的第x位二进制修改为1需要加上多少
            cost += (1ll &amp;#x3C;&amp;#x3C; x) - ((1ll &amp;#x3C;&amp;#x3C; (x + 1)) - 1ll &amp;#x26; b[j]);
        }
        if (cost &gt; k) return cost; //超过k就返回，避免数据溢出
    }
    return cost;
}

void solve() {
    std::cin &gt;&gt; n &gt;&gt; q;
    for(int i = 1; i &amp;#x3C;= n ; i ++)
        std::cin &gt;&gt; a[i];
    while(q --){
        int k;
        std::cin &gt;&gt; k;
        memset(ans, 0, sizeof(ans));
        for (int i = 1; i &amp;#x3C;= n; i++)
            b[i] = a[i];
        for (int i = 60; i &gt;= 0; i--) {//检查第i位结果与运算的结果是否可能为1
            int cost = getCost(i, k);
            if (cost &amp;#x3C;= k) {//花费在操作次数范围内
                ans[i] = 1;//与运算结果可以为1
                k -= cost;
                for (int j = 1; j &amp;#x3C;= n; j++) {
                    if ((b[j] &amp;#x26; (1ll &amp;#x3C;&amp;#x3C; i)) == 0) {
                        //通过或运算将2^i位修改为1，再通过与运算将后面数字清0
                        b[j] = ((b[j] | (1ll &amp;#x3C;&amp;#x3C; i)) &amp;#x26; (1ll &amp;#x3C;&amp;#x3C; i));
                    }
                }
            }
        }
        int res = 0;
        for (int i = 0; i &amp;#x3C;= 60; i++)
            res |= (ans[i] &amp;#x3C;&amp;#x3C; i);//这里ans[i]如果不是long long类型也会发生溢出
        std::cout &amp;#x3C;&amp;#x3C; res &amp;#x3C;&amp;#x3C; endl;
    }
}


signed main () {
    std::ios::sync_with_stdio (false);
    std::cin.tie (nullptr), std::cout.tie (nullptr);
    int Lazy_boy = 1;
    // std::cin &gt;&gt; Lazy_boy;
    while (Lazy_boy--)
        solve ();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/11.BXtmYD8T.webp"/><enclosure url="/_astro/11.BXtmYD8T.webp"/></item><item><title>Hello2024</title><link>https://santisify.top/blog/old/cf1919</link><guid isPermaLink="true">https://santisify.top/blog/old/cf1919</guid><description>codeforces-hello2024(A-C)</description><pubDate>Mon, 01 Jan 2024 23:46:17 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1919/problem/A&quot;&gt;Wallet Exchange&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Alice&lt;/code&gt;有&lt;code&gt;a&lt;/code&gt;个硬币,&lt;code&gt;Bob&lt;/code&gt;有&lt;code&gt;b&lt;/code&gt;个硬币,双方轮流进行以下操作: 1.与对方交换硬币,或者保留现有硬币. 2.取出一个硬币
无法进行操作的人判定为输,总是从&lt;code&gt;Alice&lt;/code&gt;开始操作
问:哪位获得胜利&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们可以把游戏看作是轮流取硬币,取得最后一个硬币的为胜利
那么我们就可以直接判断&lt;code&gt;a+b&lt;/code&gt;奇偶性就可以得出答案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int a, b;
    std::cin &gt;&gt; a &gt;&gt; b;
    std::cout &amp;#x3C;&amp;#x3C; ((a + b) % 2 ? &quot;Alice&quot; : &quot;Bob&quot;) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1919/problem/B&quot;&gt;Plus-Minus Split&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;略&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;简单看下样例就猜出来是&lt;code&gt;+&lt;/code&gt;与&lt;code&gt;-&lt;/code&gt;的差值的绝对值&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int n;
    std::string s;
    std::cin &gt;&gt; n &gt;&gt; s;
    int cnt1 = 0;
    for (auto i: s)
        cnt1 += (i == &apos;+&apos;);
    std::cout &amp;#x3C;&amp;#x3C; abs((n - cnt1) - cnt1) &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1919/problem/C&quot;&gt;Grouping Increases&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目大意&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src=&quot;http://tuchuang.lazy-boy-acmer.cn/images/202404060855225.png&quot; alt=&quot;image.png&quot;&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;贪心&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int n, ans = 0;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n, 0ll);
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
    std::vector&amp;#x3C;int&gt; A, B;
    A.push_back(INF), B.push_back(INF);
    for (int i = 0; i &amp;#x3C; n; i++) {
        int x = A.back(), y = B.back();
        if (x &amp;#x3C; y) {
            if (a[i] &amp;#x3C;= x)
                A.push_back(a[i]);
            else if (a[i] &amp;#x3C;= y)
                B.push_back(a[i]);
            else {
                A.push_back(a[i]);
                ans++;
            }
        } else {
            if (a[i] &amp;#x3C;= y)
                B.push_back(a[i]);
            else if (a[i] &amp;#x3C;= x)
                A.push_back(a[i]);
            else {
                B.push_back(a[i]);
                ans++;
            }
        }
    }
    std::cout &amp;#x3C;&amp;#x3C; ans &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/9.D3LlgscO.webp"/><enclosure url="/_astro/9.D3LlgscO.webp"/></item><item><title>Goodbye2023</title><link>https://santisify.top/blog/old/goodbye2023</link><guid isPermaLink="true">https://santisify.top/blog/old/goodbye2023</guid><description>codeforces-goodbye2023(A-C)</description><pubDate>Sun, 31 Dec 2023 23:44:55 GMT</pubDate><content:encoded>&lt;h2&gt;A &lt;a href=&quot;https://codeforces.com/contest/1916/problem/A&quot;&gt;2023&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;给定 &lt;code&gt;n&lt;/code&gt;个数，让我们判断是否能与 &lt;code&gt;m&lt;/code&gt;个数相乘后可以得到 &lt;code&gt;2023&lt;/code&gt;，并且将这些数输出出来&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们只需要判断这些数能否被2023整除。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int s = 2023;
    int n, m;
    std::cin &gt;&gt; n &gt;&gt; m;
    std::vector&amp;#x3C;int&gt; a(n);
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
    for (int i = 0; i &amp;#x3C; n; i++)
        if (s % a[i]) {
            std::cout &amp;#x3C;&amp;#x3C; &quot;NO&quot; &amp;#x3C;&amp;#x3C; endl;
            return;
        } else {
            s /= a[i];
        }
    std::cout &amp;#x3C;&amp;#x3C; &quot;YES&quot; &amp;#x3C;&amp;#x3C; endl;
    for (int i = 0; i &amp;#x3C; m - 1; i++)
        std::cout &amp;#x3C;&amp;#x3C; 1 &amp;#x3C;&amp;#x3C; &quot; &quot;;
    std::cout &amp;#x3C;&amp;#x3C; s &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;B &lt;a href=&quot;https://codeforces.com/contest/1916/problem/B&quot;&gt;Two Divisors&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;选择一个 (1 &amp;#x3C;= x &amp;#x3C;= 1e9) 的数。同时满足 1≤a&amp;#x3C;b&amp;#x3C;x 的条件。
对于给定的数 a、b，你需要求出 x 的值。
如果有整数 k，使得 x=y⋅k, 则数 y 是数 x 的除数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;首先你得要知道，你需要这个值有a和b，那么是和lcm(a,b)是有关系的，默认a&amp;#x3C;b，然后其次你发现，lcm(a,b)如果和b一样的话，那么你的这个值，实际上他会选不到b，那么我们需要把这个值增加一些，并且不影响答案。那么这个增加的值实际上就是lcm(a,b)/a，首先这题有解，那么lcm(a,b)一定有a和b的因子，由于他们是最大的，所以我们需要乘一个小数，去使得能选到b，但是a和b仍然是最大两个，所以当你的lcm(a,b)不是b的时候，那么lcm(a,b)就是答案，否则，答案应该乘上一个小值，那么乘上什么值是正确的，首先我们要理解，肯定不能让a变成除了b以外的数字，那么就是乘上一个lcm(a,b)/a，乘上这个值之后，他们的因子没有出现新大数。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-cpp&quot;&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int a, b;
    std::cin &gt;&gt; a &gt;&gt; b;
    if (b % a)
        std::cout &amp;#x3C;&amp;#x3C; a * b / std::gcd(a, b) &amp;#x3C;&amp;#x3C; endl;
    else
        std::cout &amp;#x3C;&amp;#x3C; b * b / a &amp;#x3C;&amp;#x3C; endl;
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;C &lt;a href=&quot;https://codeforces.com/contest/1916/problem/C&quot;&gt;Training Before the Olympiad&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;题目描述&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;玛莎和奥丽雅马上就要参加一个重要的团队奥林匹克竞赛了。为此，玛莎建议和奥丽雅玩一个热身游戏：
有一个大小为 n 的数组 a。马莎先走，然后大家轮流走。每一步都可以用下面的操作顺序来描述：
如果数组的大小为 1，游戏结束。
当前下棋的棋手选择两个不同的索引 i、j(1≤i,j≤|a|)，并执行以下操作--从数组中移除 ai 和 aj，并在数组中添加一个等于⌊ai+aj2⌋⋅2 的数字。换句话说，首先将 ai 和 aj 的和除以 2(向下舍入)，然后将结果乘以 2。
玛莎的目标是最大化最终数字，而奥丽雅的目标是最小化最终数字。
玛莎和奥丽雅决定在初始数组 a 的每个非空前缀上进行博弈，并请求您的帮助。
对于每个 k(=1,2,...,n)，请回答下面的问题。让数组 a 的前 k 个元素出现在游戏中，索引分别为 1,2,...,k。在双方都下得最好的情况下，最后会剩下多少个元素？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;解题思路&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;我们只需要注意到奇数加偶数会产生一个-1，那么我们就是要算怎么样计算这个值，我们发现，无论哪两个数字都会产生一个偶数，所以偶数是最后消去的，我们如果想要答案最大，那么一定是优先消除掉奇数，如果想要答案最小，一定是奇数和偶数组合，那么我们记录奇数和偶数的数量，在面对到奇数的时候，这个减去的多少个-1，我们可以算出他的过程，注意对于只有一个数字的情况要特判。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#include &amp;#x3C;bits/stdc++.h&gt;

#define int long long
#define endl &apos;\n&apos;
#define fix(n) std::fixed &amp;#x3C;&amp;#x3C; std::setprecision(n)
[[maybe_unused]]typedef std::pair&amp;#x3C;int, int&gt; pii;
[[maybe_unused]]const int INF = 1e18 + 50;

void solve() {
    int n;
    std::cin &gt;&gt; n;
    std::vector&amp;#x3C;int&gt; a(n);
    for (int i = 0; i &amp;#x3C; n; i++) std::cin &gt;&gt; a[i];
    int S = 0, C = 0;
    for (int i = 0; i &amp;#x3C; n; i++) {
        S += a[i], C += a[i] &amp;#x26; 1;
        if (i == 0)
            std::cout &amp;#x3C;&amp;#x3C; a[i] &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n - 1];
        else
            std::cout &amp;#x3C;&amp;#x3C; S - C / 3 - (C % 3 == 1) &amp;#x3C;&amp;#x3C; &quot; \n&quot;[i == n - 1];
    }
}

signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr), std::cout.tie(nullptr);
    int Lazy_boy_ = 1;
    std::cin &gt;&gt; Lazy_boy_;
    while (Lazy_boy_--)
        solve();
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;</content:encoded><h:img src="/_astro/8.Q_Bi3OUW.webp"/><enclosure url="/_astro/8.Q_Bi3OUW.webp"/></item></channel></rss>